[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_)