[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ns] Patch for scheduler to use 64 bit integers when available.



Good afternoon-

When running very large simulations or simulations with high bandwidth links,
the scheduler can run out of unique identifers because it uses a 32 bit signed
integer for this purpose (max 2^31-1 = 2.1*10^9 events; for gigabit links at
1*10^9bps you can see how this would be a problem). If you've ever seen the
"Scheduler: UID space exhausted!" error you'll probably be interested in this.

I wrote up a patch to allow those whose hardware or compiler (such as gcc)
support 64 bit integers to use those integers. It's just a bunch of #ifdefs to
check for availability and use int64_t if it's available, so backward
compatibility is retained.

The attached patch is against the current snapshot/CVS version (scheduler.cc
version 1.58, scheduler.h version 1.18).


-Eric

--------------------------------------------
 Eric H. Weigle   CCS-1, RADIANT team
 [email protected]     Los Alamos National Lab
 (505) 665-4937   http://home.lanl.gov/ehw/
--------------------------------------------
--- scheduler.h	Fri Nov  3 12:43:00 2000
+++ scheduler.h.new	Fri Nov  3 13:05:49 2000
@@ -46,7 +46,11 @@
 	Event* next_;		/* event list */
 	Handler* handler_;	/* handler to call when event ready */
 	double time_;		/* time at which event is ready */
+#ifdef HAVE_INT64
+	int64_t uid_;		/* unique ID */
+#else
 	int uid_;		/* unique ID */
+#endif // HAVE_INT64
 	Event() : time_(0), uid_(0) {}
 };
 
@@ -71,7 +75,11 @@
 	virtual void run();			// execute the simulator
 	virtual void cancel(Event*) = 0;	// cancel event
 	virtual void insert(Event*) = 0;	// schedule event
+#ifdef HAVE_INT64
+	virtual Event* lookup(int64_t uid) = 0;	// look for event
+#else
 	virtual Event* lookup(int uid) = 0;	// look for event
+#endif // HAVE_INT64
 	virtual Event* deque() = 0;		// next event (removes from q)
 	inline double clock() const {		// simulator virtual time
 		return (clock_);
@@ -90,7 +98,11 @@
 	double clock_;
 	int halted_;
 	static Scheduler* instance_;
+#ifdef HAVE_INT64
+	static int64_t uid_;
+#else
 	static int uid_;
+#endif // HAVE_INT64
 };
 
 class ListScheduler : public Scheduler {
@@ -99,7 +111,11 @@
 	virtual void cancel(Event*);
 	virtual void insert(Event*);
 	virtual Event* deque();
+#ifdef HAVE_INT64
+	virtual Event* lookup(int64_t uid);
+#else
 	virtual Event* lookup(int uid);
+#endif // HAVE_INT64
 protected:
 	Event* queue_;
 };
@@ -118,7 +134,11 @@
 	virtual void insert(Event* e) {
 		hp_->heap_insert(e->time_, (void*) e);
 	}
+#ifdef HAVE_INT64
+	virtual Event* lookup(int64_t uid);
+#else
 	virtual Event* lookup(int uid);
+#endif // HAVE_INT64
 	virtual Event* deque();
 protected:
 	Heap* hp_;
@@ -130,7 +150,11 @@
 	virtual ~CalendarScheduler();
 	virtual void cancel(Event*);
 	virtual void insert(Event*);
+#ifdef HAVE_INT64
+	virtual Event* lookup(int64_t uid);
+#else
 	virtual Event* lookup(int uid);
+#endif // HAVE_INT64
 	virtual Event* deque();
 
 protected:
--- scheduler.cc	Fri Nov  3 13:29:11 2000
+++ scheduler.cc.new	Fri Nov  3 13:33:27 2000
@@ -50,7 +50,11 @@
 #endif
 
 Scheduler* Scheduler::instance_;
+#ifdef HAVE_INT64
+int64_t Scheduler::uid_ = 1;
+#else
 int Scheduler::uid_ = 1;
+#endif // HAVE_INT64
 
 // class AtEvent : public Event {
 // public:
@@ -80,10 +84,19 @@
 		fprintf(stderr, "warning: ns Scheduler::schedule: scheduling event\n\twith negative delay (%f) at time %f.\n", delay, clock_);
 	}
 
+#ifdef HAVE_INT64
+	if (uid_ < 0) {
+		// No "INT_MAX" for long longs. Would be 9223372036854775807 if defined (2^64-1)
+		// This space should never overflow - negative means somebody messed with uid_
+		fprintf(stderr, "Scheduler: Bad UID in schedule!\n");
+		abort();
+	}
+#else
 	if (uid_ < 0 || uid_ >= INT_MAX) {
 		fprintf(stderr, "Scheduler: UID space exhausted!\n");
 		abort();
 	}
+#endif // HAVE_INT64
 	e->uid_ = uid_++;
 	e->handler_ = h;
 	double t = clock_ + delay;
@@ -222,7 +235,11 @@
 			e->proc_ = new char[n + 1];
 			strcpy(e->proc_, proc);
 			schedule(&at_handler, e, 0);
+#ifdef HAVE_INT64
+			sprintf(tcl.buffer(), "%llu", e->uid_);
+#else
 			sprintf(tcl.buffer(), "%u", e->uid_);
+#endif // HAVE_INT64
 			tcl.result(tcl.buffer());
 		}
 		return (TCL_OK);
@@ -242,7 +259,11 @@
 				return (TCL_ERROR);
 			}
 			schedule(&at_handler, e, delay);
+#ifdef HAVE_INT64
+			sprintf(tcl.buffer(), "%llu", e->uid_);
+#else
 			sprintf(tcl.buffer(), "%u", e->uid_);
+#endif // HAVE_INT64
 			tcl.result(tcl.buffer());
 			return (TCL_OK);
 		}
@@ -258,8 +279,11 @@
 	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_);
+#ifdef HAVE_INT64
+		printf("t:%f uid: %lld handler: %p\n", p->time_, p->uid_, p->handler_);
+#else
+		printf("t:%f uid: %d handler: %p\n", p->time_, p->uid_, p->handler_);
+#endif // HAVE_INT64
 	}
 }
 
@@ -301,7 +325,11 @@
 	e->uid_ = - e->uid_;
 }
 
+#ifdef HAVE_INT64
+Event* ListScheduler::lookup(int64_t uid)
+#else
 Event* ListScheduler::lookup(int uid)
+#endif // HAVE_INT64
 {
 	Event* e;
 	for (e = queue_; e != 0; e = e->next_)
@@ -508,7 +536,11 @@
 	}
 } class_heap_sched;
 
+#ifdef HAVE_INT64
+Event* HeapScheduler::lookup(int64_t uid)
+#else
 Event* HeapScheduler::lookup(int uid)
+#endif // HAVE_INT64
 {
 	Event* e;
 	
@@ -765,7 +797,11 @@
 	abort();
 }
 
+#ifdef HAVE_INT64
+Event* CalendarScheduler::lookup(int64_t uid)
+#else
 Event* CalendarScheduler::lookup(int uid)
+#endif // HAVE_INT64
 {
 	for (int i = 0; i < nbuckets_; i++)
 		for (Event* p = buckets_[i]; p != NULL; p = p->next_)