00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdlib.h>
00045 #include <math.h>
00046 #include <assert.h>
00047
00048 #include "config.h"
00049 #include "tclcl.h"
00050 #include "srm-topo.h"
00051 #include "scheduler.h"
00052
00053 #define SRM_DEBUG
00054
00055
00056 Topology::Topology(int nn, int src) : idx_(nn), src_(src)
00057 {
00058 node_ = new SrmNode[nn];
00059 for (int i = 0; i < nn; i ++)
00060 node_[i].id(i);
00061
00062 bind("src_", &src_);
00063 bind("delay_", &delay_);
00064 bind("D_", &D_);
00065 bind("frac_", &frac_);
00066
00067
00068 bind("det_", &det_);
00069 bind("rtt_est_", &rtt_est_);
00070 bind("rand_", &rand_);
00071 }
00072
00073 Topology::~Topology() {
00074 delete [] node_;
00075 }
00076
00077 int Topology::command(int argc, const char*const* argv)
00078 {
00079
00080 if (argc == 3) {
00081 if (strcmp(argv[1], "flood") == 0) {
00082 flood(0, atoi(argv[2]));
00083 return (TCL_OK);
00084 }
00085 }
00086 return (TclObject::command(argc, argv));
00087 }
00088
00089 SrmNode* Topology::node(int nn)
00090 {
00091 if (nn < 0 || nn >= idx_) return 0;
00092 return &(node_[nn]);
00093 }
00094
00095
00096 static class LineClass : public TclClass {
00097 public:
00098 LineClass() : TclClass("Topology/Line") {}
00099 TclObject* create(int, const char*const* argv) {
00100 int nn = atoi(argv[4]);
00101 return (new Line(nn, 0));
00102 }
00103 } class_line_topo;
00104
00105
00106 double Line::backoff(int dst)
00107 {
00108 double rtt;
00109
00110 if (topology->rtt_estimated() == 1)
00111 rtt = delay(dst, 0);
00112 else rtt = D_ * frac_;
00113 double b;
00114 double sqroot = sqrt(rtt);
00115 double r = Random::uniform(0.0, 1.0);
00116
00117 switch(c2func_) {
00118 case LOG :
00119 b = rtt * (det_ + rand_ * r * log(rtt)/log(D_));
00120 break;
00121 case SQRT :
00122 b = rtt * (det_ + rand_ * r * sqroot/sqrt(D_));
00123 break;
00124 case LINEAR :
00125 b = rtt * (det_ + rand_ * r * rtt/D_);
00126 break;
00127 case CONSTANT :
00128 b = rtt * (det_ + rand_ * r * 1.);
00129 break;
00130 default:
00131
00132 b = 0.0;
00133 assert (false);
00134 break;
00135 }
00136 return b;
00137 }
00138
00139 #ifdef SRM_BIMODAL
00140 double Line::backoff(int dst)
00141 {
00142 double rtt;
00143 if (topology->rtt_estimated() == 1)
00144 rtt = delay(dst, 0);
00145 else rtt = D_ * frac_;
00146
00147 double rbackoff;
00148 double p = Random::uniform(0.0, 1.0);
00149 int bin = 0;
00150 int copies = c_;
00151 int size = topology->idx();
00152
00153 if (p <= copies * 1./size) {
00154 rbackoff = Random::uniform(0.0, alpha_);
00155 bin = 0;
00156 } else {
00157 rbackoff = Random::uniform(beta_, 1.0 + beta_);
00158 bin = 1;
00159 }
00160
00161 return (rtt * (det_ + rand_ * rbackoff));
00162 }
00163 #endif
00164
00165 Interface_List* Line::oif(int node, int iif=SRM_NOIF)
00166 {
00167
00168 Interface_List *ilist = new Interface_List;
00169
00170
00171 if ((iif <= node && node >= idx_ - 1) || (iif > node && node == 0))
00172 return 0;
00173
00174 if (iif == SRM_NOIF)
00175 {
00176 ilist->append(node + 1);
00177 ilist->append(node - 1);
00178 } else if (iif <= node)
00179 ilist->append(node + 1);
00180 else
00181 ilist->append(node - 1);
00182 return (ilist);
00183 }
00184
00185 double Line::delay(int src, int dst)
00186 {
00187 if (src == 0 || dst == 0)
00188 return D_ + delay_ * abs(dst - src - 1);
00189 else
00190 return delay_ * abs(dst - src);
00191 }
00192
00193
00194 double Star::delay(int src, int dst)
00195 {
00196 if (src == 0 || dst == 0)
00197 return D_;
00198 else
00199 return delay_;
00200 }
00201
00202
00203
00204
00205 double BTree::delay(int src, int dst)
00206 {
00207 double src_ht = 0;
00208 double dst_ht = 0;
00209
00210 if (src > 0)
00211 src_ht = 1 + floor(log(src)/log(2));
00212 if (dst > 0)
00213 dst_ht = 1 + floor(log(dst)/log(2));
00214
00215 if (src == 0 || dst == 0)
00216 return D_ + delay_ * abs(int (dst_ht - src_ht - 1));
00217 else
00218 return delay_ * abs(int (dst_ht - src_ht));
00219 }
00220
00221
00222
00223
00224
00225
00226 void Line::flood(int start, int seqno)
00227 {
00228 SRM_Event *se = new SRM_Event(seqno, SRM_DATA, start);
00229 node_[start].send(se);
00230 }
00231
00232
00233
00234
00235
00236 static class BTreeClass : public TclClass {
00237 public:
00238 BTreeClass() : TclClass("Topology/BTree") {}
00239 TclObject* create(int, const char*const* argv) {
00240 int nn = atoi(argv[4]);
00241 return (new BTree(nn, 0));
00242 }
00243 } class_btree_topo;
00244
00245
00246
00247
00248
00249
00250 double BTree::backoff(int id)
00251 {
00252 double rtt;
00253 if (topology->rtt_estimated())
00254 rtt = delay(id, 0);
00255 else rtt = D_ * frac_;
00256
00257 double r = Random::uniform(0.0, 1.0);
00258 double b;
00259 double sqroot = sqrt(rtt);
00260 double D = topology->D();
00261
00262 switch(c2func_) {
00263 case LOG :
00264 b = rtt * (det_ + rand_ * r * log(rtt)/log(D));
00265 break;
00266 case SQRT :
00267 b = rtt * (det_ + rand_ * r * sqroot/sqrt(D));
00268 break;
00269 case LINEAR :
00270 b = rtt * (det_ + rand_ * r * rtt/D);
00271 break;
00272 case CONSTANT :
00273 b = rtt * (det_ + rand_ * r * 1.);
00274 break;
00275 default:
00276
00277 b = 0.0;
00278 assert (false);
00279 break;
00280 }
00281 return b;
00282 }
00283
00284 Interface_List* BTree::oif(int node, int iif=SRM_NOIF)
00285 {
00286
00287 Interface_List *ilist = new Interface_List;
00288
00289
00290
00291
00292
00293 if (iif == SRM_NOIF) {
00294 if (node == 0) {
00295 ilist->append(1);
00296 }
00297 else {
00298 ilist->append(2 * node + 1);
00299 ilist->append(2 * node);
00300 int k = (int)floor(.5 * node);
00301 ilist->append(k);
00302 }
00303 } else if (iif <= node) {
00304 ilist->append(2 * node + 1);
00305 ilist->append(2 * node);
00306 }
00307
00308
00309 else if (iif == 2 * node + 1) {
00310 if (node == 0)
00311 return ilist;
00312
00313 ilist->append(2 * node);
00314 ilist->append((int) floor(.5 * node));
00315 } else if (iif == 2 * node) {
00316 ilist->append(2 * node + 1);
00317 ilist->append((int)floor(.5 * node));
00318 }
00319 return (ilist);
00320 }
00321
00322
00323
00324
00325
00326 static class StarClass : public TclClass {
00327 public:
00328 StarClass() : TclClass("Topology/Star") {}
00329 TclObject* create(int, const char*const* argv) {
00330 int nn = atoi(argv[4]);
00331 return (new Star(nn, 0));
00332 }
00333 } class_star_topo;
00334
00335
00336
00337
00338
00339
00340 void SrmNode::dump_packet(SRM_Event *e)
00341 {
00342 #ifdef SRM_DEBUG
00343 tprintf(("(type %d) (in %d) -- @ %d --> \n", e->type(), e->iif(), id_));
00344 #endif
00345 }
00346
00347
00348
00349
00350 void SrmNode::send(SRM_Event *e)
00351 {
00352
00353
00354
00355
00356 int nn;
00357 Scheduler& s = Scheduler::instance();
00358 SRM_Event *copy;
00359 Interface *p;
00360 Interface_List *ilist = topology->oif(id_, e->iif());
00361 if (e->iif() < 0)
00362 e->iif(id_);
00363
00364 if (ilist) {
00365 for (p=ilist->head_; p; p=p->next_) {
00366 nn = p->in_;
00367 int t = e->type();
00368
00369 int snum = e->seqno();
00370 SrmNode *next = topology->node(nn);
00371 if (next) {
00372 copy = new SRM_Event(snum, t, id_);
00373 s.schedule(next, copy,
00374 topology->delay(id_, nn));
00375 }
00376 }
00377 }
00378 delete ilist;
00379 delete e;
00380 }
00381
00382
00383
00384
00385
00386
00387 void SrmNode::handle(Event* event)
00388 {
00389 SRM_Event *srm_event = (SRM_Event *) event;
00390 int type = srm_event->type();
00391 int seqno = srm_event->seqno();
00392
00393
00394
00395 switch (type) {
00396 case SRM_DATA :
00397 if (seqno != expected_)
00398 sched_nack(seqno);
00399 expected_ = seqno;
00400 break;
00401
00402 case SRM_PENDING_RREQ :
00403 tprintf(("Fired RREQ (node %d)\n", id_));
00404 remove(seqno, SRM_NO_SUPPRESS);
00405 srm_event->type(SRM_RREQ);
00406 break;
00407
00408 case SRM_RREQ :
00409
00410 remove(seqno, SRM_SUPPRESS);
00411 break;
00412
00413 default :
00414 tprintf(("panic: node(%d) Unexpected type %d\n", id_, type));
00415 return;
00416 }
00417 #ifdef SRM_STAR
00418 if (type == SRM_RREQ || type == SRM_DATA) {
00419 delete srm_event;
00420 return;
00421 }
00422 #endif
00423 send(srm_event);
00424 return;
00425 }
00426
00427
00428
00429
00430
00431 void SrmNode::sched_nack(int seqno)
00432 {
00433 double backoff, time;
00434 Scheduler& s = Scheduler::instance();
00435 SRM_Event *event = new SRM_Event(seqno,
00436 SRM_PENDING_RREQ, SRM_NOIF);
00437 append(event);
00438
00439 backoff = topology->backoff(id_);
00440 time = backoff + s.clock();
00441
00442 s.schedule(this, event, backoff);
00443 }
00444
00445 void SrmNode::append(SRM_Event *e)
00446 {
00447 SRM_Request *req = new SRM_Request(e);
00448 req->next_ = pending_;
00449 pending_ = req;
00450 }
00451
00452
00453 void SrmNode::remove(int seqno, int flag)
00454 {
00455 SRM_Request *curr, *prev;
00456 SRM_Event *ev;
00457
00458 if (!pending_)
00459 return;
00460 for (curr=pending_, prev=0; curr; curr=curr->next_)
00461 {
00462 ev = curr->event_;
00463 if (ev->seqno() == seqno) {
00464 if (!prev)
00465 pending_ = curr->next_;
00466 else {
00467 prev->next_ = curr->next_;
00468 prev = curr;
00469 }
00470 if (flag == SRM_SUPPRESS) {
00471 curr->cancel_timer();
00472 }
00473 delete curr;
00474 }
00475 }
00476 }
00477
00478
00479 SRM_Event::SRM_Event(SRM_Event *e)
00480 {
00481 seqno_ = e->seqno();
00482 type_ = e->type();
00483 iif_ = e->iif();
00484 }
00485
00486 SRM_Request::~SRM_Request() {}
00487
00488 void SRM_Request::cancel_timer()
00489 {
00490 if (event_) {
00491 Scheduler& s = Scheduler::instance();
00492 s.cancel(event_);
00493
00494 }
00495 }
00496
00497 void Interface_List::append(int in)
00498 {
00499 Interface *i = new Interface(in);
00500 i->next_ = head_;
00501 head_ = i;
00502 }
00503
00504 Interface_List::~Interface_List()
00505 {
00506 Interface *p, *next;
00507 for (p=head_; p; p=next)
00508 {
00509 next = p->next_;
00510 delete p;
00511 }
00512 }
00513
00514 void BTree::flood(int start, int seqno)
00515 {
00516 SRM_Event *se = new SRM_Event(seqno, SRM_DATA, SRM_NOIF);
00517 node_[start].send(se);
00518 }
00519
00520 void Star::flood(int start, int seqno)
00521 {
00522 SRM_Event *se = new SRM_Event(seqno, SRM_DATA, start);
00523 node_[start].send(se);
00524 }
00525
00526 Interface_List* Star::oif(int node, int iif=SRM_NOIF)
00527 {
00528 int i;
00529 Interface_List *ilist = new Interface_List;
00530
00531
00532 for (i = 0; i < topology->idx(); i ++)
00533 {
00534 if (i != node && i != iif) {
00535 ilist->append(i);
00536 }
00537 }
00538
00539 return (ilist);
00540 }
00541
00542
00543
00544
00545 double Star::backoff(int id)
00546 {
00547 double rtt = topology->delay(id, 0);
00548 double rbackoff;
00549 double p = Random::uniform(0.0, 1.0);
00550 static int bin = 0;
00551 int copies = c_;
00552 int size = topology->idx();
00553
00554 if (p <= copies * 1./size) {
00555 rbackoff = Random::uniform(0.0, alpha_);
00556 bin ++;
00557 } else {
00558 rbackoff = Random::uniform(beta_, 1.0 + beta_);
00559 }
00560 return (rtt * (det_ + rand_ * rbackoff));
00561 }
00562
00563
00564 #ifdef SRM_BIMODAL
00565 double BTree::backoff(int dst)
00566 {
00567 double height = floor(log(dst)/log(2));
00568
00569 double D = topology->D();
00570 double rtt = delay_ * height + D;
00571 double p = Random::uniform(0.0, 1.0);
00572 double rbackoff;
00573
00574 static int bin = 0;
00575 int copies = c_;
00576 int size = topology->idx();
00577
00578 if (p <= copies * 1./size) {
00579 rbackoff = Random::uniform(0.0, alpha_);
00580 bin ++;
00581 } else {
00582 rbackoff = Random::uniform(1.0 + alpha_, 2.0);
00583 }
00584 return (rtt * (det_ + rand_ * rbackoff));
00585 }
00586 #endif