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 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <sys/types.h>
00038 #include <math.h>
00039
00040 #include "tfrc-sink.h"
00041 #include "formula-with-inverse.h"
00042 #include "flags.h"
00043
00044 static class TfrcSinkClass : public TclClass {
00045 public:
00046 TfrcSinkClass() : TclClass("Agent/TFRCSink") {}
00047 TclObject* create(int, const char*const*) {
00048 return (new TfrcSinkAgent());
00049 }
00050 } class_tfrcSink;
00051
00052
00053 TfrcSinkAgent::TfrcSinkAgent() : Agent(PT_TFRC_ACK), nack_timer_(this)
00054 {
00055 bind("packetSize_", &size_);
00056 bind("InitHistorySize_", &hsz);
00057 bind("NumFeedback_", &NumFeedback_);
00058 bind ("AdjustHistoryAfterSS_", &adjust_history_after_ss);
00059 bind ("printLoss_", &printLoss_);
00060 bind ("algo_", &algo);
00061 bind ("PreciseLoss_", &PreciseLoss_);
00062 bind ("numPkts_", &numPkts_);
00063
00064
00065 bind ("NumSamples_", &numsamples);
00066 bind ("discount_", &discount);
00067 bind ("smooth_", &smooth_);
00068 bind ("ShortIntervals_", &ShortIntervals_);
00069
00070
00071 bind ("history_", &history);
00072
00073
00074 bind("minlc_", &minlc);
00075
00076 bind("bytes_", &bytes_);
00077 rtt_ = 0;
00078 tzero_ = 0;
00079 last_timestamp_ = 0;
00080 last_arrival_ = 0;
00081 last_report_sent=0;
00082 total_received_ = 0;
00083 total_losses_ = 0;
00084 total_dropped_ = 0;
00085
00086 maxseq = -1;
00087 maxseqList = -1;
00088 rcvd_since_last_report = 0;
00089 losses_since_last_report = 0;
00090 loss_seen_yet = 0;
00091 lastloss = 0;
00092 lastloss_round_id = -1 ;
00093 numPktsSoFar_ = 0;
00094
00095 rtvec_ = NULL;
00096 tsvec_ = NULL;
00097 lossvec_ = NULL;
00098
00099
00100 last_sample = 0;
00101
00102
00103 false_sample = 0;
00104 sample = NULL ;
00105 weights = NULL ;
00106 mult = NULL ;
00107 losses = NULL ;
00108 count_losses = NULL ;
00109 sample_count = 1 ;
00110 mult_factor_ = 1.0;
00111 init_WALI_flag = 0;
00112
00113
00114 avg_loss_int = -1 ;
00115 loss_int = 0 ;
00116
00117
00118 sendrate = 0 ;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 int TfrcSinkAgent::new_loss(int i, double tstamp)
00133 {
00134 double time_since_last_loss_interval = tsvec_[i%hsz]-lastloss;
00135 if ((time_since_last_loss_interval > rtt_)
00136 && (PreciseLoss_ == 0 || (round_id > lastloss_round_id))) {
00137 lastloss = tstamp;
00138 lastloss_round_id = round_id ;
00139 if (time_since_last_loss_interval < 2.0 * rtt_ &&
00140 algo == WALI) {
00141 count_losses[0] = 1;
00142 }
00143 return TRUE;
00144 } else return FALSE;
00145 }
00146
00147 double TfrcSinkAgent::estimate_tstamp(int before, int after, int i)
00148 {
00149 double delta = (tsvec_[after%hsz]-tsvec_[before%hsz])/(after-before) ;
00150 double tstamp = tsvec_[before%hsz]+(i-before)*delta ;
00151 return tstamp;
00152 }
00153
00154
00155
00156
00157 void TfrcSinkAgent::recv(Packet *pkt, Handler *)
00158 {
00159 hdr_tfrc *tfrch = hdr_tfrc::access(pkt);
00160 hdr_flags* hf = hdr_flags::access(pkt);
00161 double now = Scheduler::instance().clock();
00162 double p = -1;
00163 int ecnEvent = 0;
00164 int congestionEvent = 0;
00165 int UrgentFlag = 0;
00166 int newdata = 0;
00167
00168 if (algo == WALI && !init_WALI_flag) {
00169 init_WALI () ;
00170 }
00171 rcvd_since_last_report ++;
00172 total_received_ ++;
00173
00174 bytes_ += hdr_cmn::access(pkt)->size();
00175
00176 if (maxseq < 0) {
00177
00178 newdata = 1;
00179 maxseq = tfrch->seqno - 1 ;
00180 maxseqList = tfrch->seqno;
00181 rtvec_=(double *)malloc(sizeof(double)*hsz);
00182 tsvec_=(double *)malloc(sizeof(double)*hsz);
00183 lossvec_=(char *)malloc(sizeof(double)*hsz);
00184 if (rtvec_ && lossvec_) {
00185 int i;
00186 for (i = 0; i < hsz ; i ++) {
00187 lossvec_[i] = UNKNOWN;
00188 rtvec_[i] = -1;
00189 tsvec_[i] = -1;
00190 }
00191 }
00192 else {
00193 printf ("error allocating memory for packet buffers\n");
00194 abort ();
00195 }
00196 }
00197
00198
00199 int seqno = tfrch->seqno ;
00200 fsize_ = tfrch->fsize;
00201 int oldmaxseq = maxseq;
00202
00203
00204 if ((seqno > maxseq) ||
00205 (seqno > maxseqList && lossvec_[seqno%hsz] == UNKNOWN )) {
00206 if (seqno > maxseqList + 1)
00207 ++ numPktsSoFar_;
00208 UrgentFlag = tfrch->UrgentFlag;
00209 round_id = tfrch->round_id ;
00210 rtt_=tfrch->rtt;
00211 tzero_=tfrch->tzero;
00212 psize_=tfrch->psize;
00213 sendrate = tfrch->rate;
00214 last_arrival_=now;
00215 last_timestamp_=tfrch->timestamp;
00216 rtvec_[seqno%hsz]=now;
00217 tsvec_[seqno%hsz]=last_timestamp_;
00218 if (hf->ect() == 1 && hf->ce() == 1) {
00219
00220 lossvec_[seqno%hsz] = ECN_RCVD;
00221 ++ total_losses_;
00222 losses_since_last_report++;
00223 if (new_loss(seqno, tsvec_[seqno%hsz])) {
00224 ecnEvent = 1;
00225 lossvec_[seqno%hsz] = ECNLOST;
00226 }
00227 if (algo == WALI) {
00228 ++ losses[0];
00229 }
00230 } else lossvec_[seqno%hsz] = RCVD;
00231 }
00232 if (seqno > maxseq) {
00233 int i = maxseq + 1;
00234 while (i < seqno) {
00235
00236
00237 lossvec_[i%hsz] = UNKNOWN;
00238 ++ i;
00239 ++ total_losses_;
00240 ++ total_dropped_;
00241 }
00242 }
00243 if (seqno > maxseqList &&
00244 (ecnEvent || numPktsSoFar_ >= numPkts_ ||
00245 tsvec_[seqno%hsz] - tsvec_[maxseqList%hsz] > rtt_)) {
00246
00247
00248
00249
00250
00251
00252 int i = maxseqList ;
00253 while(i < seqno) {
00254 if (lossvec_[i%hsz] == UNKNOWN) {
00255 rtvec_[i%hsz]=now;
00256 tsvec_[i%hsz]=estimate_tstamp(oldmaxseq, seqno, i);
00257 if (new_loss(i, tsvec_[i%hsz])) {
00258 congestionEvent = 1;
00259 lossvec_[i%hsz] = LOST;
00260 } else {
00261
00262
00263 lossvec_[i%hsz] = NOT_RCVD;
00264 }
00265 if (algo == WALI) {
00266 ++ losses[0];
00267 }
00268 losses_since_last_report++;
00269 }
00270 i++;
00271 }
00272 maxseqList = seqno;
00273 numPktsSoFar_ = 0;
00274 } else if (seqno == maxseqList + 1) {
00275 maxseqList = seqno;
00276 numPktsSoFar_ = 0;
00277 }
00278 if (seqno > maxseq) {
00279 maxseq = tfrch->seqno ;
00280
00281
00282 if ((algo == WALI) && (loss_seen_yet ==0) &&
00283 (tfrch->seqno - oldmaxseq > 1 || ecnEvent )) {
00284 UrgentFlag = 1 ;
00285 loss_seen_yet = 1;
00286 if (adjust_history_after_ss) {
00287 p = adjust_history(tfrch->timestamp);
00288 }
00289
00290 }
00291 if ((rtt_ > SMALLFLOAT) &&
00292 (now - last_report_sent >= rtt_/NumFeedback_)) {
00293 UrgentFlag = 1 ;
00294 }
00295 }
00296 if (UrgentFlag || ecnEvent || congestionEvent) {
00297 nextpkt(p);
00298 }
00299 Packet::free(pkt);
00300 }
00301
00302 double TfrcSinkAgent::est_loss ()
00303 {
00304 double p = 0 ;
00305 switch (algo) {
00306 case WALI:
00307 p = est_loss_WALI () ;
00308 break;
00309 case EWMA:
00310 p = est_loss_EWMA () ;
00311 break;
00312 case RBPH:
00313 p = est_loss_RBPH () ;
00314 break;
00315 case EBPH:
00316 p = est_loss_EBPH () ;
00317 break;
00318 default:
00319 printf ("invalid algo specified\n");
00320 abort();
00321 break ;
00322 }
00323 return p;
00324 }
00325
00326
00327
00328
00329 double TfrcSinkAgent::est_thput ()
00330 {
00331 double time_for_rcv_rate;
00332 double now = Scheduler::instance().clock();
00333 double thput = 1 ;
00334
00335 if ((rtt_ > 0) && ((now - last_report_sent) >= rtt_)) {
00336
00337 time_for_rcv_rate = (now - last_report_sent);
00338 if (rcvd_since_last_report > 0) {
00339 thput = rcvd_since_last_report/time_for_rcv_rate;
00340 }
00341 }
00342 else {
00343
00344 if (rtt_ > 0){
00345 double last = rtvec_[maxseq%hsz];
00346 int rcvd = 0;
00347 int i = maxseq;
00348 while (i > 0) {
00349 if (lossvec_[i%hsz] == RCVD) {
00350 if ((rtvec_[i%hsz] + rtt_) > last)
00351 rcvd++;
00352 else
00353 break ;
00354 }
00355 i--;
00356 }
00357 if (rcvd > 0)
00358 thput = rcvd/rtt_;
00359 }
00360 }
00361 return thput ;
00362 }
00363
00364
00365
00366
00367 void TfrcSinkAgent::nextpkt(double p) {
00368
00369 sendpkt(p);
00370
00371
00372 if (rtt_ > 0.0 && NumFeedback_ > 0)
00373 nack_timer_.resched(1.5*rtt_/NumFeedback_);
00374 }
00375
00376
00377
00378
00379 void TfrcSinkAgent::sendpkt(double p)
00380 {
00381 double now = Scheduler::instance().clock();
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 if (last_arrival_ >= last_report_sent) {
00392
00393 Packet* pkt = allocpkt();
00394 if (pkt == NULL) {
00395 printf ("error allocating packet\n");
00396 abort();
00397 }
00398
00399 hdr_tfrc_ack *tfrc_ackh = hdr_tfrc_ack::access(pkt);
00400
00401 tfrc_ackh->seqno=maxseq;
00402 tfrc_ackh->timestamp_echo=last_timestamp_;
00403 tfrc_ackh->timestamp_offset=now-last_arrival_;
00404 tfrc_ackh->timestamp=now;
00405 tfrc_ackh->NumFeedback_ = NumFeedback_;
00406 if (p < 0)
00407 tfrc_ackh->flost = est_loss ();
00408 else
00409 tfrc_ackh->flost = p;
00410 tfrc_ackh->rate_since_last_report = est_thput ();
00411 tfrc_ackh->losses = losses_since_last_report;
00412 if (total_received_ <= 0)
00413 tfrc_ackh->true_loss = 0.0;
00414 else
00415 tfrc_ackh->true_loss = 1.0 *
00416 total_losses_/(total_received_+total_dropped_);
00417 last_report_sent = now;
00418 rcvd_since_last_report = 0;
00419 losses_since_last_report = 0;
00420 send(pkt, 0);
00421 }
00422 }
00423
00424 int TfrcSinkAgent::command(int argc, const char*const* argv)
00425 {
00426 if (argc == 3) {
00427 if (strcmp(argv[1], "weights") == 0) {
00428
00429
00430
00431
00432
00433
00434 char *w ;
00435 w = (char *)calloc(strlen(argv[2])+1, sizeof(char)) ;
00436 if (w == NULL) {
00437 printf ("error allocating w\n");
00438 abort();
00439 }
00440 strcpy(w, (char *)argv[2]);
00441 numsamples = atoi(strtok(w,"+"));
00442 sample = (int *)malloc((numsamples+1)*sizeof(int));
00443 losses = (int *)malloc((numsamples+1)*sizeof(int));
00444 count_losses = (int *)malloc((numsamples+1)*sizeof(int));
00445 weights = (double *)malloc((numsamples+1)*sizeof(double));
00446 mult = (double *)malloc((numsamples+1)*sizeof(double));
00447 fflush(stdout);
00448 if (sample && weights) {
00449 int count = 0 ;
00450 while (count < numsamples) {
00451 sample[count] = 0;
00452 losses[count] = 1;
00453 count_losses[count] = 0;
00454 mult[count] = 1;
00455 char *w;
00456 w = strtok(NULL, "+");
00457 if (w == NULL)
00458 break ;
00459 else {
00460 weights[count++] = atof(w);
00461 }
00462 }
00463 if (count < numsamples) {
00464 printf ("error in weights string %s\n", argv[2]);
00465 abort();
00466 }
00467 sample[count] = 0;
00468 losses[count] = 1;
00469 count_losses[count] = 0;
00470 weights[count] = 0;
00471 mult[count] = 1;
00472 free(w);
00473 return (TCL_OK);
00474 }
00475 else {
00476 printf ("error allocating memory for smaple and weights:2\n");
00477 abort();
00478 }
00479 }
00480 }
00481 return (Agent::command(argc, argv));
00482 }
00483
00484 void TfrcNackTimer::expire(Event *) {
00485 a_->nextpkt(-1);
00486 }
00487
00488 void TfrcSinkAgent::print_loss(int sample, double ave_interval)
00489 {
00490 double now = Scheduler::instance().clock();
00491 double drops = 1/ave_interval;
00492
00493
00494 printf ("time: %7.5f loss_rate: %7.5f \n", now, drops);
00495 printf ("time: %7.5f sample 0: %5d loss_rate: %7.5f \n",
00496 now, sample, drops);
00497
00498
00499 }
00500
00501 void TfrcSinkAgent::print_loss_all(int *sample)
00502 {
00503 double now = Scheduler::instance().clock();
00504 printf ("%f: sample 0: %5d 1: %5d 2: %5d 3: %5d 4: %5d\n",
00505 now, sample[0], sample[1], sample[2], sample[3], sample[4]);
00506 }
00507
00508 void TfrcSinkAgent::print_losses_all(int *losses)
00509 {
00510 double now = Scheduler::instance().clock();
00511 printf ("%f: losses 0: %5d 1: %5d 2: %5d 3: %5d 4: %5d\n",
00512 now, losses[0], losses[1], losses[2], losses[3], losses[4]);
00513 }
00514
00515 void TfrcSinkAgent::print_count_losses_all(int *count_losses)
00516 {
00517 double now = Scheduler::instance().clock();
00518 printf ("%f: count? 0: %5d 1: %5d 2: %5d 3: %5d 4: %5d\n",
00519 now, count_losses[0], count_losses[1], count_losses[2], count_losses[3], count_losses[4]);
00520 }
00521
00523
00525
00526
00530 double TfrcSinkAgent::est_loss_WALI ()
00531 {
00532 int i;
00533 double ave_interval1, ave_interval2;
00534 int ds ;
00535
00536 if (!init_WALI_flag) {
00537 init_WALI () ;
00538 }
00539
00540
00541 for (i = last_sample; i <= maxseq ; i ++) {
00542 sample[0]++;
00543 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST) {
00544
00545
00546 sample_count ++;
00547 shift_array (sample, numsamples+1, 0);
00548 shift_array (losses, numsamples+1, 1);
00549 shift_array (count_losses, numsamples+1, 0);
00550 multiply_array(mult, numsamples+1, mult_factor_);
00551 shift_array (mult, numsamples+1, 1.0);
00552 mult_factor_ = 1.0;
00553 }
00554 }
00555 last_sample = maxseq+1 ;
00556
00557 if (sample_count>numsamples+1)
00558
00559 ds=numsamples+1;
00560 else
00561 ds=sample_count;
00562
00563 if (sample_count == 1 && false_sample == 0)
00564
00565 return 0;
00566
00567 if (sample_count > 1 && discount && sample[0] > 0) {
00568 double ave = weighted_average1(1, ds, 1.0, mult, weights, sample, ShortIntervals_, losses, count_losses);
00569
00570 int factor = 2;
00571 double ratio = (factor*ave)/sample[0];
00572 double min_ratio = 0.5;
00573 if ( ratio < 1.0) {
00574
00575 mult_factor_ = ratio;
00576 if (mult_factor_ < min_ratio)
00577 mult_factor_ = min_ratio;
00578 }
00579 }
00580
00581 ave_interval1 = weighted_average1(0, ds, mult_factor_, mult, weights, sample, ShortIntervals_, losses, count_losses);
00582
00583
00584
00585
00586
00587 ave_interval2 = weighted_average1(1, ds, mult_factor_, mult, weights, sample, ShortIntervals_, losses, count_losses);
00588
00589 if (ave_interval2 > ave_interval1)
00590 ave_interval1 = ave_interval2;
00591 if (ave_interval1 > 0) {
00592 if (printLoss_ > 0) {
00593 print_loss(sample[0], ave_interval1);
00594 print_loss_all(sample);
00595 if (ShortIntervals_ > 0) {
00596 print_losses_all(losses);
00597 print_count_losses_all(count_losses);
00598 }
00599 }
00600 return 1/ave_interval1;
00601 } else return 999;
00602 }
00603
00604
00605 double TfrcSinkAgent::weighted_average(int start, int end, double factor, double *m, double *w, int *sample)
00606 {
00607 int i;
00608 double wsum = 0;
00609 double answer = 0;
00610 if (smooth_ == 1 && start == 0) {
00611 if (end == numsamples+1) {
00612
00613
00614 end = end-1;
00615 }
00616
00617 for (i = start ; i < end; i++)
00618 if (i==0)
00619 wsum += m[i]*w[i+1];
00620 else
00621 wsum += factor*m[i]*w[i+1];
00622 for (i = start ; i < end; i++)
00623 if (i==0)
00624 answer += m[i]*w[i+1]*sample[i]/wsum;
00625 else
00626 answer += factor*m[i]*w[i+1]*sample[i]/wsum;
00627 return answer;
00628
00629 } else {
00630 for (i = start ; i < end; i++)
00631 if (i==0)
00632 wsum += m[i]*w[i];
00633 else
00634 wsum += factor*m[i]*w[i];
00635 for (i = start ; i < end; i++)
00636 if (i==0)
00637 answer += m[i]*w[i]*sample[i]/wsum;
00638 else
00639 answer += factor*m[i]*w[i]*sample[i]/wsum;
00640 return answer;
00641 }
00642 }
00643
00644 int TfrcSinkAgent::get_sample(int oldSample, int numLosses)
00645 {
00646 int newSample;
00647 if (numLosses == 0) {
00648 newSample = oldSample;
00649 } else {
00650 newSample = (int) floor(oldSample / numLosses);
00651 }
00652 return newSample;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 double TfrcSinkAgent::weighted_average1(int start, int end, double factor, double *m, double *w, int *sample, int ShortIntervals, int *losses, int *count_losses)
00670 {
00671 int i;
00672 int ThisSample;
00673 double wsum = 0;
00674 double answer = 0;
00675 if (smooth_ == 1 && start == 0) {
00676 if (end == numsamples+1) {
00677
00678
00679 end = end-1;
00680 }
00681
00682 for (i = start ; i < end; i++)
00683 if (i==0)
00684 wsum += m[i]*w[i+1];
00685 else
00686 wsum += factor*m[i]*w[i+1];
00687 for (i = start ; i < end; i++) {
00688 ThisSample = sample[i];
00689 if (ShortIntervals == 1 && count_losses[i] == 1) {
00690 ThisSample = get_sample(sample[i], losses[i]);
00691 }
00692 if (ShortIntervals == 2 && count_losses[i] == 1) {
00693 int adjusted_losses = int(fsize_/size_);
00694 if (losses[i] < adjusted_losses) {
00695 adjusted_losses = losses[i];
00696 }
00697 ThisSample = get_sample(sample[i], adjusted_losses);
00698 }
00699 if (i==0)
00700 answer += m[i]*w[i+1]*ThisSample/wsum;
00701
00702 else
00703 answer += factor*m[i]*w[i+1]*ThisSample/wsum;
00704
00705 }
00706 return answer;
00707
00708 } else {
00709 for (i = start ; i < end; i++)
00710 if (i==0)
00711 wsum += m[i]*w[i];
00712 else
00713 wsum += factor*m[i]*w[i];
00714 for (i = start ; i < end; i++) {
00715 ThisSample = sample[i];
00716 if (ShortIntervals == 1 && count_losses[i] == 1) {
00717 ThisSample = get_sample(sample[i], losses[i]);
00718 }
00719 if (ShortIntervals == 2 && count_losses[i] == 1) {
00720 ThisSample = get_sample(sample[i], 7);
00721
00722 }
00723 if (i==0)
00724 answer += m[i]*w[i]*ThisSample/wsum;
00725
00726 else
00727 answer += factor*m[i]*w[i]*ThisSample/wsum;
00728
00729 }
00730 return answer;
00731 }
00732 }
00733
00734
00735 void TfrcSinkAgent::shift_array(int *a, int sz, int defval)
00736 {
00737 int i ;
00738 for (i = sz-2 ; i >= 0 ; i--) {
00739 a[i+1] = a[i] ;
00740 }
00741 a[0] = defval;
00742 }
00743 void TfrcSinkAgent::shift_array(double *a, int sz, double defval) {
00744 int i ;
00745 for (i = sz-2 ; i >= 0 ; i--) {
00746 a[i+1] = a[i] ;
00747 }
00748 a[0] = defval;
00749 }
00750
00751
00752
00753 void TfrcSinkAgent::multiply_array(double *a, int sz, double multiplier) {
00754 int i ;
00755 for (i = 1; i <= sz-1; i++) {
00756 double old = a[i];
00757 a[i] = old * multiplier ;
00758 }
00759 }
00760
00761
00762
00763
00764 double TfrcSinkAgent::adjust_history (double ts)
00765 {
00766 int i;
00767 double p;
00768 for (i = maxseq; i >= 0 ; i --) {
00769 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST ) {
00770 lossvec_[i%hsz] = NOT_RCVD;
00771 }
00772 }
00773 lastloss = ts;
00774 lastloss_round_id = round_id ;
00775 p=b_to_p(est_thput()*psize_, rtt_, tzero_, fsize_, 1);
00776 false_sample = (int)(1.0/p);
00777 sample[1] = false_sample;
00778 sample[0] = 0;
00779 losses[1] = 0;
00780 losses[0] = 1;
00781 count_losses[1] = 0;
00782 count_losses[0] = 0;
00783 sample_count++;
00784 if (printLoss_) {
00785 print_loss_all (sample);
00786 if (ShortIntervals_ == 1) {
00787 print_losses_all(losses);
00788 print_count_losses_all(count_losses);
00789 }
00790 }
00791 false_sample = -1 ;
00792 return p;
00793 }
00794
00795
00796
00797
00798
00799 void TfrcSinkAgent::init_WALI () {
00800 int i;
00801 if (numsamples < 0)
00802 numsamples = DEFAULT_NUMSAMPLES ;
00803 if (smooth_ == 1) {
00804 numsamples = numsamples + 1;
00805 }
00806 sample = (int *)malloc((numsamples+1)*sizeof(int));
00807 losses = (int *)malloc((numsamples+1)*sizeof(int));
00808 count_losses = (int *)malloc((numsamples+1)*sizeof(int));
00809 weights = (double *)malloc((numsamples+1)*sizeof(double));
00810 mult = (double *)malloc((numsamples+1)*sizeof(double));
00811 for (i = 0 ; i < numsamples+1 ; i ++) {
00812 sample[i] = 0 ;
00813 }
00814 if (smooth_ == 1) {
00815 int mid = int(numsamples/2);
00816 for (i = 0; i < mid; i ++) {
00817 weights[i] = 1.0;
00818 }
00819 for (i = mid; i <= numsamples; i ++){
00820 weights[i] = 1.0 - (i-mid)/(mid + 1.0);
00821 }
00822 } else {
00823 int mid = int(numsamples/2);
00824 for (i = 0; i < mid; i ++) {
00825 weights[i] = 1.0;
00826 }
00827 for (i = mid; i <= numsamples; i ++){
00828 weights[i] = 1.0 - (i+1-mid)/(mid + 1.0);
00829 }
00830 }
00831 for (i = 0; i < numsamples+1; i ++) {
00832 mult[i] = 1.0 ;
00833 }
00834 init_WALI_flag = 1;
00835 }
00836
00838
00840
00841 double TfrcSinkAgent::est_loss_EWMA () {
00842 double p1, p2 ;
00843 for (int i = last_sample; i <= maxseq ; i ++) {
00844 loss_int++;
00845 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST ) {
00846 if (avg_loss_int < 0) {
00847 avg_loss_int = loss_int ;
00848 } else {
00849 avg_loss_int = history*avg_loss_int + (1-history)*loss_int ;
00850 }
00851 loss_int = 0 ;
00852 }
00853 }
00854 last_sample = maxseq+1 ;
00855
00856 if (avg_loss_int < 0) {
00857 p1 = 0;
00858 } else {
00859 p1 = 1.0/avg_loss_int ;
00860 }
00861 if (loss_int == 0
00862 || avg_loss_int < 0){
00863
00864
00865
00866
00867
00868
00869
00870
00871 p2 = p1 ;
00872 } else {
00873 p2 = 1.0/(history*avg_loss_int + (1-history)*loss_int) ;
00874 }
00875 if (p2 < p1) {
00876 p1 = p2 ;
00877 }
00878 if (printLoss_ > 0) {
00879 if (p1 > 0)
00880 print_loss(loss_int, 1.0/p1);
00881 else
00882 print_loss(loss_int, 0.00001);
00883 print_loss_all(sample);
00884 }
00885 return p1 ;
00886 }
00887
00889
00891 double TfrcSinkAgent::est_loss_RBPH () {
00892
00893 double numpkts = hsz ;
00894 double p ;
00895
00896
00897 if (sendrate > 0 && rtt_ > 0) {
00898 double x = b_to_p(sendrate, rtt_, tzero_, psize_, 1);
00899 if (x > 0)
00900 numpkts = minlc/x ;
00901 else
00902 numpkts = hsz ;
00903 }
00904
00905
00906 if (numpkts > maxseq)
00907 numpkts = maxseq ;
00908 if (numpkts > hsz)
00909 numpkts = hsz ;
00910
00911 int lc = 0;
00912 int pc = 0;
00913 int i = maxseq ;
00914
00915
00916 while (pc < numpkts) {
00917 pc ++ ;
00918 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST )
00919 lc ++ ;
00920 i -- ;
00921 }
00922
00923
00924 if (lc < minlc) {
00925
00926
00927 numpkts = maxseq ;
00928 if (numpkts > hsz)
00929 numpkts = hsz ;
00930
00931 while ((lc < minlc) && (pc < numpkts)) {
00932 pc ++ ;
00933 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST )
00934 lc ++ ;
00935 i -- ;
00936
00937 }
00938 }
00939
00940 if (pc == 0)
00941 p = 0;
00942 else
00943 p = (double)lc/(double)pc ;
00944 if (printLoss_ > 0) {
00945 if (p > 0)
00946 print_loss(0, 1.0/p);
00947 else
00948 print_loss(0, 0.00001);
00949 print_loss_all(sample);
00950 }
00951 return p ;
00952 }
00953
00955
00957 double TfrcSinkAgent::est_loss_EBPH () {
00958
00959 double numpkts = hsz ;
00960 double p ;
00961
00962 int lc = 0;
00963 int pc = 0;
00964 int i = maxseq ;
00965
00966 numpkts = maxseq ;
00967 if (numpkts > hsz)
00968 numpkts = hsz ;
00969
00970 while ((lc < minlc) && (pc < numpkts)) {
00971 pc ++ ;
00972 if (lossvec_[i%hsz] == LOST || lossvec_[i%hsz] == ECNLOST)
00973 lc ++ ;
00974 i -- ;
00975 }
00976
00977 if (pc == 0)
00978 p = 0;
00979 else
00980 p = (double)lc/(double)pc ;
00981 if (printLoss_ > 0) {
00982 if (p > 0)
00983 print_loss(0, 1.0/p);
00984 else
00985 print_loss(0, 0.00001);
00986 print_loss_all(sample);
00987 }
00988 return p ;
00989 }