⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scheduler.cc

📁 可以在ns-2中进行仿真的SPIN路由协议的源码
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1994 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the Computer Systems *	Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: /usr/src/mash/repository/vint/ns-2/scheduler.cc,v 1.42 1999/01/28 23:08:21 yuriy Exp $ */#ifndef lintstatic const char rcsid[] =    "@(#) $Header: /usr/src/mash/repository/vint/ns-2/scheduler.cc,v 1.42 1999/01/28 23:08:21 yuriy Exp $ (LBL)";#endif#include <stdlib.h>#include <limits.h>#include "config.h"#include "scheduler.h"#include "packet.h"#ifdef MEMDEBUG_SIMULATIONS#include "mem-trace.h"#endifScheduler* Scheduler::instance_;int Scheduler::uid_ = 1;Scheduler::Scheduler() : clock_(SCHED_START), halted_(0){}/* * Schedule an event delay time units into the future. * The event will be dispatched to the specified handler. * We use a relative time to avoid the problem of scheduling * something in the past. */void Scheduler::schedule(Handler* h, Event* e, double delay){	if (e->uid_ > 0) {		printf("Scheduler: Event UID not valid!\n\n");		abort();	}	e->uid_ = uid_++;	e->handler_ = h;	double t = clock_ + delay;	e->time_ = t;	insert(e);}voidScheduler::run(){	instance_ = this;	Event *p;	while ((p = deque()) && !halted_) {		dispatch(p);	}}/* * dispatch a single simulator event by setting the system * virtul clock to the event's timestamp and calling its handler. * Note that the event may have side effects of placing other items * in the scheduling queue */voidScheduler::dispatch(Event* p, double t){	if (t < clock_)		fprintf(stderr, "ns: scheduler going backwards in time from %f to %f.\n", clock_, t);	clock_ = t;	p->uid_ = -p->uid_;	// being dispatched	p->handler_->handle(p);	// dispatch}voidScheduler::dispatch(Event* p){	dispatch(p, p->time_);}class AtEvent : public Event {public:	char* proc_;};class AtHandler : public Handler {public:	void handle(Event* event);} at_handler;void AtHandler::handle(Event* e){	AtEvent* at = (AtEvent*)e;	Tcl::instance().eval(at->proc_);	delete[] at->proc_;	delete at;}int Scheduler::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (instance_ == 0)		instance_ = this;	if (argc == 2) {		if (strcmp(argv[1], "run") == 0) {			/* set global to 0 before calling object reset methods */			reset();	// sets clock to zero			run();			return (TCL_OK);		} else if (strcmp(argv[1], "now") == 0) {			sprintf(tcl.buffer(), "%.17g", clock());			tcl.result(tcl.buffer());			return (TCL_OK);		} else if (strcmp(argv[1], "resume") == 0) {			halted_ = 0;			run();			return (TCL_OK);		} else if (strcmp(argv[1], "halt") == 0) {			halted_ = 1;			return (TCL_OK);		} else if (strcmp(argv[1], "clearMemTrace") == 0) {#ifdef MEMDEBUG_SIMULATIONS			extern MemTrace *globalMemTrace;			if (globalMemTrace)				globalMemTrace->diff("Sim.");#endif			return (TCL_OK);		} else if (strcmp(argv[1], "is-running") == 0) {			sprintf(tcl.buffer(), "%d", !halted_);			return (TCL_OK);		} else if (strcmp(argv[1], "dumpq") == 0) {			if (!halted_) {				fprintf(stderr, "Scheduler: dumpq only allowed while halted\n");				tcl.result("0");				return (TCL_ERROR);			}			dumpq();			return (TCL_OK);		}	} else if (argc == 3) {		if (strcmp(argv[1], "at") == 0 ||		    strcmp(argv[1], "cancel") == 0) {			Event* p = lookup(atoi(argv[2]));			if (p != 0) {				/*XXX make sure it really is an atevent*/				cancel(p);				AtEvent* ae = (AtEvent*)p;				delete[] ae->proc_;				delete ae;			}		} else if (strcmp(argv[1], "at-now") == 0) {			const char* proc = argv[2];			// "at [$ns now]" may not work because of tcl's 			// string number resolution			AtEvent* e = new AtEvent;			int n = strlen(proc);			e->proc_ = new char[n + 1];			strcpy(e->proc_, proc);			schedule(&at_handler, e, 0);			sprintf(tcl.buffer(), "%u", e->uid_);			tcl.result(tcl.buffer());		}		return (TCL_OK);	} else if (argc == 4) {		if (strcmp(argv[1], "at") == 0) {			/* t < 0 means relative time: delay = -t */			double delay, t = atof(argv[2]);			const char* proc = argv[3];			AtEvent* e = new AtEvent;			int n = strlen(proc);			e->proc_ = new char[n + 1];			strcpy(e->proc_, proc);			delay = (t < 0) ? -t : t - clock();			if (delay < 0) {				tcl.result("can't schedule command in past");				return (TCL_ERROR);			}			schedule(&at_handler, e, delay);			sprintf(tcl.buffer(), "%u", e->uid_);			tcl.result(tcl.buffer());			return (TCL_OK);		}	}	return (TclObject::command(argc, argv));}voidScheduler::dumpq(){	Event *p;	printf("Contents of scheduler queue (events) [cur time: %f]---\n",		clock());	while ((p = deque()) != NULL) {		printf("t:%f uid: %d handler: %p\n",			p->time_, p->uid_, p->handler_);	}}class ListScheduler : public Scheduler {public:	inline ListScheduler() : queue_(0) {}	virtual void cancel(Event*);	virtual void insert(Event*);	virtual Event* deque();	virtual Event* lookup(int uid);protected:	Event* queue_;};static class ListSchedulerClass : public TclClass {public:	ListSchedulerClass() : TclClass("Scheduler/List") {}	TclObject* create(int /* argc */, const char*const* /* argv */) {		return (new ListScheduler);	}} class_list_sched;void ListScheduler::insert(Event* e){	double t = e->time_;	Event** p;#ifdef SPIN	if (lookup(e->uid_)) {		printf("ERROR!!!!  Event NOT inserted.\n");		return;		//exit(1);	}#endif	for (p = &queue_; *p != 0; p = &(*p)->next_)		if (t <= (*p)->time_)			break;	e->next_ = *p;	*p = e;}/* * Cancel an event.  It is an error to call this routine * when the event is not actually in the queue.  The caller * must free the event if necessary; this routine only removes * it from the scheduler queue. */void ListScheduler::cancel(Event* e){	Event** p;	if (e->uid_ <= 0)	// event not in queue		return;	for (p = &queue_; *p != e; p = &(*p)->next_)		if (*p == 0)			abort();	*p = (*p)->next_;	e->uid_ = - e->uid_;}Event* ListScheduler::lookup(int uid){	Event* e;	for (e = queue_; e != 0; e = e->next_)		if (e->uid_ == uid)			break;	return (e);}Event*ListScheduler::deque(){ 	Event* e = queue_;	if (e)		queue_ = e->next_;	return (e);}#include "heap.h"class HeapScheduler : public Scheduler {public:	inline HeapScheduler() { hp_ = new Heap; } 	virtual void cancel(Event* e) {		if (e->uid_ <= 0)			return;		e->uid_ = - e->uid_;		hp_->heap_delete((void*) e);	}	virtual void insert(Event* e) {		hp_->heap_insert(e->time_, (void*) e);	}	virtual Event* lookup(int uid);	virtual Event* deque();protected:	Heap* hp_;};static class HeapSchedulerClass : public TclClass {public:	HeapSchedulerClass() : TclClass("Scheduler/Heap") {}	TclObject* create(int /* argc */, const char*const* /* argv */) {		return (new HeapScheduler);	}} class_heap_sched;Event* HeapScheduler::lookup(int uid){	Event* e;		for (e = (Event*) hp_->heap_iter_init(); e;	     e = (Event*) hp_->heap_iter())		if (e->uid_ == uid)			break;	return e;}Event*HeapScheduler::deque(){	return ((Event*) hp_->heap_extract_min());}/* * Calendar queue scheduler contributed by * David Wetherall <djw@juniper.lcs.mit.edu> * March 18, 1997. * * A calendar queue basically hashes events into buckets based on * arrival time. */class CalendarScheduler : public Scheduler {public:	CalendarScheduler();	virtual ~CalendarScheduler();	virtual void cancel(Event*);	virtual void insert(Event*);	virtual Event* lookup(int uid);	virtual Event* deque();protected:	int resizeenabled_;	double width_;	double oneonwidth_;	double buckettop_;	double last_clock_;	int nbuckets_;	int buckbits_;	int lastbucket_;	int top_threshold_;	int bot_threshold_;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -