00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef lint
00022 static const char rcsid[] =
00023 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/splay-scheduler.cc,v 1.5 2002/12/02 21:15:43 yuri Exp $";
00024 #endif
00025
00052 #include <scheduler.h>
00053 #include <assert.h>
00054
00055
00056 static class SplaySchedulerClass : public TclClass
00057 {
00058 public:
00059 SplaySchedulerClass() : TclClass("Scheduler/Splay") {}
00060 TclObject* create(int , const char*const* ) {
00061 return (new SplayScheduler);
00062 }
00063 } class_splay_sched;
00064
00065 #undef LEFT
00066 #undef RIGHT
00067 #define LEFT(e) ((e)->prev_)
00068 #define RIGHT(e) ((e)->next_)
00069
00070 #define ROTATE_RIGHT(t, x) \
00071 do { \
00072 LEFT(t) = RIGHT(x); \
00073 RIGHT(x) = (t); \
00074 (t) = (x); \
00075 } while(0)
00076
00077 #define ROTATE_LEFT(t, x) \
00078 do { \
00079 RIGHT(t) = LEFT(x); \
00080 LEFT(x) = (t); \
00081 (t) = (x); \
00082 } while(0)
00083 #define LINK_LEFT(l, t) \
00084 do { \
00085 RIGHT(l) = (t); \
00086 (l) = (t); \
00087 (t) = RIGHT(t); \
00088 } while (0)
00089 #define LINK_RIGHT(r, t) \
00090 do { \
00091 LEFT(r) = (t); \
00092 (r) = (t); \
00093 (t) = LEFT(t); \
00094 } while (0)
00095
00096 void
00097 SplayScheduler::insert(Event *n)
00098 {
00099 Event *l;
00100 Event *r;
00101 Event *t;
00102 Event *x;
00103
00104 ++qsize_;
00105
00106 double time = n->time_;
00107
00108 if (root_ == 0) {
00109 LEFT(n) = RIGHT(n) = 0;
00110 root_ = n;
00111
00112 return;
00113 }
00114 t = root_;
00115 root_ = n;
00116 l = n;
00117 r = n;
00118 for (;;) {
00119 if (time < t->time_) {
00120 x = LEFT(t);
00121 if (x == 0) {
00122 LEFT(r) = t;
00123 RIGHT(l) = 0;
00124 break;
00125 }
00126 if (time < x->time_) {
00127 ROTATE_RIGHT(t, x);
00128 }
00129 LINK_RIGHT(r, t);
00130 if (t == 0) {
00131 RIGHT(l) = 0;
00132 break;
00133 }
00134 } else {
00135 x = RIGHT(t);
00136 if (x == 0) {
00137 RIGHT(l) = t;
00138 LEFT(r) = 0;
00139 break;
00140 }
00141 if (time >= x->time_) {
00142 ROTATE_LEFT(t, x);
00143 }
00144 LINK_LEFT(l, t);
00145 if (t == 0) {
00146 LEFT(r) = 0;
00147 break;
00148 }
00149
00150 }
00151 }
00152
00153
00154
00155 x = LEFT(n);
00156 LEFT(n) = RIGHT(n);
00157 RIGHT(n) = x;
00158
00159 }
00160
00161 const Event *
00162 SplayScheduler::head()
00163 {
00164 Event *t;
00165 Event *l;
00166 #if 1
00167 if (root_ == 0)
00168 return 0;
00169 for (t = root_; (l = LEFT(t)); t = l)
00170 ;
00171
00172 return t;
00173 #else
00174 Event *ll;
00175 Event *lll;
00176
00177 if (root_ == 0)
00178 return 0;
00179
00180 t = root_;
00181 l = LEFT(t);
00182
00183 if (l == 0) {
00184 return t;
00185 }
00186 for (;;) {
00187 ll = LEFT(l);
00188 if (ll == 0) {
00189 return l;
00190 }
00191
00192 lll = LEFT(ll);
00193 if (lll == 0) {
00194 return ll;
00195 }
00196
00197
00198 LEFT(t) = ll;
00199 LEFT(l) = RIGHT(ll);
00200 RIGHT(ll) = l;
00201
00202 t = ll;
00203 l = lll;
00204 }
00205 #endif
00206 }
00207
00208 Event *
00209 SplayScheduler::deque()
00210 {
00211 Event *t;
00212 Event *l;
00213 Event *ll;
00214 Event *lll;
00215
00216 if (root_ == 0)
00217 return 0;
00218
00219 --qsize_;
00220
00221 t = root_;
00222 l = LEFT(t);
00223
00224 if (l == 0) {
00225 root_ = RIGHT(t);
00226
00227 return t;
00228 }
00229 for (;;) {
00230 ll = LEFT(l);
00231 if (ll == 0) {
00232 LEFT(t) = RIGHT(l);
00233
00234 return l;
00235 }
00236
00237 lll = LEFT(ll);
00238 if (lll == 0) {
00239 LEFT(l) = RIGHT(ll);
00240
00241 return ll;
00242 }
00243
00244
00245 LEFT(t) = ll;
00246 LEFT(l) = RIGHT(ll);
00247 RIGHT(ll) = l;
00248
00249 t = ll;
00250 l = lll;
00251 }
00252 }
00253
00254 void
00255 SplayScheduler::cancel(Event *e)
00256 {
00257
00258 if (e->uid_ <= 0)
00259 return;
00260
00261 Event **t;
00262
00263 if (e == root_) {
00264 t = &root_;
00265 } else {
00266
00267
00268
00269 for (t = &root_; *t;) {
00270 t = ((e->time_ > (*t)->time_) ||
00271 ((e->time_ == (*t)->time_) && e->uid_ > (*t)->uid_))
00272 ? &RIGHT(*t) : &LEFT(*t);
00273 if (*t == e)
00274 break;
00275 }
00276 if (*t == 0) {
00277 fprintf(stderr, "did not find it\n");
00278 abort();
00279 }
00280 }
00281
00282 e->uid_ = -e->uid_;
00283 --qsize_;
00284
00285 if (RIGHT(e) == 0) {
00286 *t = LEFT(e);
00287 LEFT(e) = 0;
00288
00289 return;
00290 }
00291 if (LEFT(e) == 0) {
00292 *t = RIGHT(e);
00293 RIGHT(e) = 0;
00294
00295 return;
00296 }
00297
00298
00299 Event *p = RIGHT(e), *q = LEFT(p);
00300
00301 if (q == 0) {
00302
00303 *t = p;
00304 LEFT(p) = LEFT(e);
00305
00306 return;
00307 }
00308 for (; LEFT(q); p = q, q = LEFT(q))
00309 ;
00310
00311
00312 *t = q;
00313 LEFT(p) = RIGHT(q);
00314 LEFT(q) = LEFT(e);
00315 RIGHT(q) = RIGHT(e);
00316 RIGHT(e) = LEFT(e) = 0;
00317
00318 }
00319
00320
00321 Event *
00322 SplayScheduler::lookup(scheduler_uid_t uid)
00323 {
00324 lookup_uid_ = uid;
00325 return uid_lookup(root_);
00326 }
00327
00328 Event *
00329 SplayScheduler::uid_lookup(Event *root)
00330 {
00331 if (root == 0)
00332 return 0;
00333 if (root->uid_ == lookup_uid_)
00334 return root;
00335
00336 Event *res = uid_lookup(LEFT(root));
00337
00338 if (res)
00339 return res;
00340
00341 return uid_lookup(RIGHT(root));
00342 }
00343
00344 int
00345 SplayScheduler::validate(Event *root)
00346 {
00347 int size = 0;
00348 if (root) {
00349 ++size;
00350 assert(LEFT(root) == 0 || root->time_ >= LEFT(root)->time_);
00351 assert(RIGHT(root) == 0 || root->time_ <= RIGHT(root)->time_);
00352 size += validate(LEFT(root));
00353 size += validate(RIGHT(root));
00354 return size;
00355 }
00356 return 0;
00357 }