asim.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * asim.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: asim.cc,v 1.11 2005/08/25 18:58:01 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 
00047 #include "config.h"
00048 
00049 #include <math.h>
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <string.h>
00053 #include <strings.h>
00054 #include <assert.h>
00055 #include <iostream>
00056 
00057 #include "agent.h"
00058 
00059 // Integration of Ashish's RED and asim
00060 #define _RED_ROUTER_MAIN_
00061 #include "asim.h"
00062 
00063 #define sp " " 
00064 
00065 typedef struct c{
00066   int no; // no of edges in the connection
00067   double delay; // total delay;
00068   double drop; // total drop prob
00069   double p_tput;
00070   double t;
00071   // The short flow stuff
00072   int is_sflow; // boolean to indicate whether there is a short flow
00073   double slambda; // The arrival rate of the connections
00074   int snopkts; // average of no of packets each short flow givies
00075   RedRouter * red;
00076   int scaled; // Whether this flow has been scaled or not
00077 }flow_stats;
00078 
00079 typedef struct n{
00080   int red; // flag to notify whether its a red queue or not
00081   double pmin, pmax, minth, maxth; // RED parameters
00082   double lambda; // Arrival rate - Packets per second
00083   double plambda; // Temp lambda value. previous lambda
00084   double tlambda;
00085   double mu; // Consumption rate - Packets per second
00086   double prop; // Propagation delay of the link
00087   double qdelay; // Store the queuing delay for each link
00088   int    buffer; // Total buffer
00089   double drop; // probability of drop
00090   int nflows; // Number of flows through this link
00091   int *theflows; // The flows through this link
00092   double scaled_lambda;
00093   double unscaled_lambda;
00094 
00095   double utput; // unscaled tput 
00096   double uc; // unscaled capacity
00097 
00098   // For ashish
00099   RedRouter * redrouter;
00100 
00101 }link_stats;
00102 
00103 
00104 class asim : public NsObject{
00105 
00106 public:
00107 
00108   // data structures 
00109   int nConnections; // Number of connections
00110   int K, MaxHops; // 
00111   int nLinks; // Number of links 
00112   int **Adj; // Stores the edge list of each connection
00113   int *nAdj; // Stores the no of edges per connection
00114   
00115   link_stats* links;
00116   flow_stats* flows;
00117   
00118   double min(double x, double y){
00119     return (x<y)?x:y;
00120   }
00121 
00122   double padhye(double rtt, double p){
00123     
00124     double rto = 1;
00125     double t=1;
00126     t = rtt*sqrt(2*p/3)+rto*min(1,(3*sqrt(3*p/8)))*p*(1+32*p*p);
00127     return min(20/rtt,1/t);
00128     
00129   }
00130   
00131   double Po(double rho, int K){
00132     
00133     if(rho==1)
00134       return 1.0/(K+1);
00135     
00136     double t;
00137     t=(1.0*(1-rho))/(1.0-pow(rho,K));
00138     return t;
00139     
00140   }
00141 
00142   double Pk(double rho, int K, int k){
00143     
00144     if(rho==1)
00145       return 1.0/(K+1);
00146     
00147     double t;
00148     t=(1-rho)*pow(rho,k);
00149     t/=1-pow(rho,K+1);
00150     return t;
00151   }  
00152 
00153   double Lq(double rho, int K){
00154 
00155     double t1,t2;
00156     
00157     if(rho==1){
00158       return (1.0*K*(K-1))/(2.0*(K+1));
00159     }
00160     
00161     t1=rho*1.0/(1-rho);
00162     t2=rho*1.0/(1-pow(rho,K+1));
00163     t2*=K*pow(rho,K)+1;
00164     return (t1-t2)/2;
00165     
00166   }
00167   
00168   int command (int argc, const char*const* argv){
00169 
00170     if (strcmp(argv[1], "run") == 0) {
00171       int niter=0;
00172       for(int i=0; i<20; i++){
00173     CalcLinkDelays(1);
00174     CalcPerFlowDelays();
00175     newupdate(niter);
00176       }
00177       //PrintResults();  
00178       return (TCL_OK);
00179     }
00180     
00181     if (strcmp(argv[1], "readinput") == 0) {
00182       GetInputs((char*)argv[2]);
00183       //cout << "All inputs properly obtained from " << argv[2] <<endl ; 
00184       return (TCL_OK);
00185     }
00186 
00187     if (strcmp(argv[1], "get-link-drop") == 0) {
00188       cout << "Hi";
00189       Tcl& tcl = Tcl::instance();
00190       tcl.resultf("%lf",get_link_drop(atoi(argv[2])));
00191       return (TCL_OK);
00192     }
00193 
00194     if (strcmp(argv[1], "get-link-delay") == 0) {
00195       Tcl& tcl = Tcl::instance();
00196       tcl.resultf("%lf",get_link_delay(atoi(argv[2])));
00197       return (TCL_OK);
00198     }  
00199 
00200     if (strcmp(argv[1], "get-link-tput") == 0) {
00201       Tcl& tcl = Tcl::instance();
00202       tcl.resultf("%lf",get_link_tput(atoi(argv[2])));
00203       return (TCL_OK);
00204     }  
00205 
00206     if (strcmp(argv[1], "get-flow-tput") == 0) {
00207       Tcl& tcl = Tcl::instance();
00208       tcl.resultf("%lf",get_flow_tput(atoi(argv[2])));
00209       return (TCL_OK);
00210     }
00211 
00212     if (strcmp(argv[1], "get-flow-delay") == 0) {
00213       Tcl& tcl = Tcl::instance();
00214       tcl.resultf("%lf",get_flow_delay(atoi(argv[2])));
00215       return (TCL_OK);
00216     }      
00217 
00218     if (strcmp(argv[1], "get-flow-drop") == 0) {
00219       Tcl& tcl = Tcl::instance();
00220       tcl.resultf("%lf",get_flow_drop(atoi(argv[2])));
00221       return (TCL_OK);
00222     }
00223     return 0;
00224   }
00225   
00226   double get_link_drop(int x){
00227     assert(x<nLinks);
00228     return links[x].drop;
00229   }
00230 
00231   double get_link_delay(int x){
00232     assert(x<nLinks);
00233     return links[x].qdelay + links[x].prop ;
00234   }
00235 
00236   double get_link_qdelay(int x){
00237     assert(x<nLinks);
00238     return links[x].qdelay;
00239   }
00240 
00241   double get_link_pdelay(int x){
00242     assert(x<nLinks);
00243     return links[x].prop;
00244   }
00245 
00246   double get_link_tput(int x){
00247     assert(x<nLinks);
00248     return links[x].lambda;
00249   }
00250 
00251   double get_flow_delay(int x){
00252     assert(x<nConnections);
00253     return flows[x].delay;
00254   }
00255 
00256   double get_flow_tput(int x){
00257     assert(x<nConnections);
00258     return flows[x].p_tput;
00259   }
00260 
00261   double get_flow_drop(int x){
00262     assert(x<nConnections);
00263     return flows[x].drop;
00264   }
00265 
00266   void GetInputs(char *argv) {
00267     
00268     // error if usage is wrong 
00269     /*    
00270     if (argc != 2) {
00271       fprintf(stderr,"Usage: %s  <InputFile>\n", argv[0]);
00272       exit(-1); 
00273       }*/
00274     
00275   // No error 
00276   MaxHops = 0;
00277   // K = atoi(argv[1]);
00278   // assert(K >= 1);
00279 
00280 
00281   // Init links and connections 
00282   nConnections = 0;
00283   nLinks = 0;
00284 
00285   // Start the reading process
00286   FILE *f;
00287   f = fopen(argv,"r");
00288   assert(f);
00289 
00290   char s[256];
00291   while (fgets(s, 255, f)) {
00292 
00293     // Read a token 
00294     char *t;
00295     t = strtok(s, " \t\n");
00296 
00297     // Ignore comments 
00298     if (!t || !t[0] || (t[0] == '#') || !strncasecmp(t, "comment", 6))
00299       continue;
00300     
00301     // Define the number of connections
00302     if (!strcasecmp(t,"n")) {
00303       t = strtok(NULL," \t");
00304       assert(t);
00305       nConnections = atoi(t);
00306       assert(nConnections > 0);
00307       assert(nConnections >= 0);
00308       nAdj = new int[nConnections];
00309       Adj = new int*[nConnections];
00310       flows = new flow_stats[nConnections];
00311       for (int i=0; i<nConnections; ++i)
00312     nAdj[i] = -1;
00313       continue;
00314     }
00315 
00316     // Define the number of links
00317     else if (!strcasecmp(t,"m")) {
00318 
00319       t = strtok(NULL," \t");
00320       assert(t);
00321       // #of links defined
00322       nLinks = atoi(t);
00323       assert(nLinks > 0);
00324       // Allocate space for sotring lambdas and mus
00325       links = new link_stats[nLinks];
00326       continue;
00327     }
00328 
00329     // Enter each route 
00330     else if (!strcasecmp(t,"route")) {
00331 
00332       assert (nConnections > 0);
00333       assert (nLinks > 0);
00334       t = strtok(NULL," \t");
00335       assert(t);
00336       int i = atoi(t);
00337       assert(i > 0 && i<= nConnections);
00338       i--;
00339  
00340      // We dunno whether this will be short flow specs
00341       flows[i].is_sflow = 0; // Lets assume its a normal flow
00342       flows[i].drop = 0; // Assume ideal case to start off
00343       flows[i].scaled = 0; // Not scaled as yet
00344 
00345       t = strtok(NULL," \t");
00346       assert(t);
00347       nAdj[i] = atoi(t);
00348       assert(nAdj[i] > 0 && nAdj[i] <= nLinks);
00349       Adj[i] = new int[nAdj[i]];
00350       for (int j=0; j<nAdj[i]; ++j) {
00351     t = strtok(NULL," \t");
00352     assert(t);
00353     int l = atoi(t);
00354     assert(l > 0 && l <= nLinks);
00355     l--;
00356     Adj[i][j] = l;
00357       }
00358 
00359       if (MaxHops < nAdj[i]) MaxHops = nAdj[i];
00360 
00361       
00362       t = strtok(NULL," \t");
00363       // assert(t);
00364     
00365       // Short flows stuff 
00366 
00367       if (t && !strcasecmp(t,"sh")) {
00368     // There are short flows on this route.
00369     flows[i].is_sflow = 1;
00370       
00371     // read the slambda
00372     t = strtok(NULL," \t");
00373     assert(t);
00374     double  tmp = atof(t);
00375     flows[i].slambda = tmp;
00376 
00377     // read the snopkts
00378     t = strtok(NULL," \t");
00379     assert(t);
00380     int  tmpi = atoi(t);
00381     flows[i].snopkts = tmpi;
00382       }
00383       
00384       continue;
00385     }
00386 
00387     else if(!strcasecmp(t,"link")){
00388 
00389       assert (nLinks > 0);
00390 
00391       // Get the link number
00392       t = strtok(NULL," \t");
00393       assert(t);
00394       int i = atoi(t);
00395       assert(i > 0 && i<= nLinks);
00396       i--;
00397 
00398       // Get the prop delay
00399       t = strtok(NULL," \t");
00400       assert(t);
00401       double p = atof(t);
00402       assert(p>=0); 
00403       links[i].prop = p;
00404 
00405       // Get the lambda for this link
00406       t = strtok(NULL," \t");
00407       assert(t);
00408       p = atof(t);
00409       assert(p>=0);
00410       links[i].lambda = 0;
00411       links[i].tlambda = p;
00412       links[i].plambda = p;
00413 
00414       // Get the mu for this link
00415       t = strtok(NULL," \t");
00416       assert(t);
00417       p = atof(t);
00418       assert(p>=0);
00419       links[i].mu = p;
00420 
00421       // Get the buffer for this link
00422       t = strtok(NULL," \t");
00423       assert(t);
00424       int t1 = atoi(t);
00425       assert(t1>0);
00426       links[i].buffer = t1;
00427 
00428       // Check for RED Q or not
00429       t = strtok(NULL," \t");
00430       if(t && !strcasecmp(t,"red")){
00431 
00432     // must be a red queue
00433     // input red parameters
00434     // all parameters between 0 and 1
00435     links[i].red=1;
00436     // get minth
00437     t = strtok(NULL," \t");
00438     double dt = atof(t); 
00439     //assert(dt>=0 && dt<=1);
00440     links[i].minth=dt;
00441 
00442     // get pmin
00443     t = strtok(NULL," \t");
00444     dt = atof(t); 
00445     //assert(dt>=0 && dt<=1);
00446     links[i].pmin=dt;
00447 
00448     // get maxth
00449     t = strtok(NULL," \t");
00450     dt = atof(t); 
00451     //assert(dt>=0 && dt<=1);
00452     links[i].maxth=dt;
00453 
00454     // get pmax
00455     t = strtok(NULL," \t");
00456     dt = atof(t); 
00457     //assert(dt>=0 && dt<=1);
00458     links[i].pmax=dt;
00459 
00460     // Invoke Ashish's RED module ... ignore pmin .....
00461 
00462     links[i].redrouter = new RedRouter((int)links[i].minth, 
00463                        (int)links[i].maxth,
00464                        links[i].pmax);
00465     assert(links[i].red);
00466 
00467       }
00468       else{
00469     links[i].red=0;
00470       }
00471     
00472       continue;
00473 
00474     }
00475 
00476     assert(0);
00477   }
00478 
00479   // Check whether everything is all right 
00480   assert (nConnections > 0);
00481   assert (nLinks > 0);
00482   int i;
00483   for (i=0; i<nConnections; ++i)
00484     assert(nAdj[i] > 0);
00485 
00486   
00487   // check all the edges and store all the connections that flow 
00488   // through a particular link
00489   
00490   for(i=0;i<nLinks;i++){
00491 
00492     //    cout << i << sp;
00493     int c=0; links[i].tlambda=0;
00494 
00495     for(int j=0;j<nConnections;j++){
00496       for(int k=0;k<nAdj[j];k++){
00497     if(Adj[j][k]==i){
00498       c++;
00499     }
00500       }
00501     }
00502     links[i].nflows=c;
00503     //cout << c << sp;
00504 
00505     if(c){
00506       links[i].theflows = new int[c];
00507       c = 0;
00508       // Store teh flows
00509       for(int j=0;j<nConnections;j++){
00510     for(int k=0;k<nAdj[j];k++){
00511       if(Adj[j][k]==i){
00512         if(flows[j].is_sflow){
00513           links[i].lambda+=flows[j].slambda*flows[j].snopkts;
00514         }
00515         links[i].theflows[c++]=j;
00516         //      cout << links[i].theflows[c-1] << sp;
00517       }
00518     }
00519       }
00520       // cout << " slambda = " << links[i].lambda;
00521     }
00522 
00523     else links[i].theflows = 0; // no connection passing through this edge
00524     //cout << endl;
00525 
00526 
00527 
00528   }
00529 
00530   /*
00531   char c= getchar();
00532 
00533   for(int i=0;i<nConnections;i++){
00534     cout << "connection" << sp << i << sp << "-"; 
00535     for(int j=0;j<nAdj[i];j++){
00536       cout << sp << Adj[i][j];
00537     }
00538     cout << endl;
00539   }
00540   */
00541   
00542 }
00543 
00544 
00545 
00546 double redFn(double minth, double pmin,
00547          double maxth, double pmax, double qlength){
00548 
00549   assert(qlength>=0 && qlength<=1);
00550   assert(pmax>=0 && pmax<=1);
00551   assert(pmin>=0 && pmin<=1);
00552   assert(minth>=0 && minth<=1);
00553   assert(maxth>=0 && maxth<=1);
00554   assert(maxth>=minth);
00555   assert(pmax>pmin);
00556 
00557   //Double t;
00558   if(qlength<minth)
00559     return 0;
00560   if(qlength>maxth)
00561     return 1;
00562   return pmin + (qlength-minth)/(pmax-pmin);
00563 
00564 }
00565 
00566 
00567 void  CalcLinkDelays(int flag = 0){
00568 
00569   // flag = 1 means enable RED
00570 
00571   // Calculate Link delays ... basically queuing delays
00572 
00573   for(int i=0; i<nLinks; i++){
00574 
00575     double rho = links[i].lambda/links[i].mu;
00576     double qlength = Lq(rho,links[i].buffer);
00577 
00578     links[i].qdelay = qlength/links[i].mu; 
00579     links[i].drop = Pk(rho,links[i].buffer,links[i].buffer);
00580 //cout << "rho = " << rho << " drop = " << links[i].drop << endl;
00581 
00582     // Special code for RED gateways
00583     if(flag){
00584       if(links[i].red){
00585     double minth, maxth, pmin, pmax, delay,p;
00586     minth = links[i].minth;
00587     maxth = links[i].maxth;
00588     pmin = links[i].pmin;
00589     pmax = links[i].pmax;
00590     /* Debo's RED approx
00591     links[i].drop = redFn(minth,pmin,maxth,pmax,qlength/links[i].buffer);
00592     qlength = (1-links[i].drop)*links[i].buffer;
00593     links[i].qdelay = qlength/links[i].mu; 
00594     */
00595     
00596     // Ashish's RED approx.
00597     p=(links[i].redrouter)->ComputeProbability(rho, delay);
00598     links[i].drop = p;
00599     qlength = Lq(rho*(1-p), links[i].buffer);
00600     links[i].qdelay = delay;
00601       }
00602     }
00603 
00604 
00605     //cout << "delay = " << links[i].qdelay << " and drop = " << links[i].drop << endl;
00606 
00607 
00608   }
00609 
00610 }
00611 
00612 void CalcPerFlowDelays(){
00613   for(int i=0; i<nConnections; i++){
00614     double d = 0, p = 1 ;
00615     // Calculate drops and delays
00616     for(int j=0;j<nAdj[i];j++){
00617       d += 2*links[Adj[i][j]].prop + links[Adj[i][j]].qdelay;
00618       p *= 1-links[Adj[i][j]].drop;
00619     }
00620     p = 1-p;
00621 
00622     flows[i].no = nAdj[i];
00623     flows[i].delay = d;
00624     flows[i].drop = p;
00625     flows[i].t = flows[i].p_tput;    
00626 
00627     // p is the end2end drop prob
00628     // If its normal flow, calculate Padhye's stuff
00629     // If its short flow, use our approximations
00630     // Nothing more
00631 
00632     
00633     if(flows[i].is_sflow){
00634       // If k flows come and each each flow has n packets to 
00635       // send then 
00636       double t = (flows[i].slambda*flows[i].snopkts);
00637       flows[i].p_tput = t/(1-p);
00638     }
00639     else{
00640       // regular bulk TCP connections, Padhye et. al.
00641       if(!p){
00642     // cout << "Oops, something wrong";
00643       }
00644       flows[i].p_tput = padhye(d,p);
00645     }
00646 
00647     //    cout << "connection " << sp << i << sp << d << sp << p; 
00648     //cout << sp << flows[i].p_tput << endl;
00649    
00650 
00651   }
00652 }
00653 
00654 void PrintData(){
00655   for(int i=0;i<nLinks;i++){
00656     cout << i << sp << links[i].lambda << sp << links[i].mu;
00657     cout << sp << links[i].buffer << endl;
00658   }
00659 }
00660 
00661 void PrintResults(){
00662   int i;
00663 
00664   for(i=0;i<nLinks;i++){
00665     // cout << i << sp << links[i].qdelay << sp << links[i].drop;
00666     cout << sp << "Qdelay = " << links[i].prop << sp << links[i].lambda;
00667     cout << sp << links[i].drop << endl;
00668   }
00669 
00670   for(i=0; i<nConnections; i++){
00671     cout << i << sp << flows[i].delay << sp;
00672     cout << flows[i].drop << sp << flows[i].p_tput << sp;
00673     cout << sp <<  endl;
00674   }
00675 
00676 }
00677 
00678 void UpdateHelper(int flag=0){
00679 
00680   // if flag = 1 then update only when link is unscaled as of now
00681   // if flag = 0 then do the usual update 
00682 
00683   int i;
00684   for(i=0; i<nLinks; i++){
00685     links[i].tlambda=0;
00686   }
00687 
00688   for(i=0; i<nConnections; i++){
00689     if(!flag || !flows[i].scaled) 
00690       for(int j=0;j<nAdj[i];j++)
00691     links[Adj[i][j]].tlambda += flows[i].p_tput;
00692     //    cout << flows[i].p_tput << "\n";
00693   }
00694 
00695 }
00696 
00697 
00698 void Update(int niter){
00699 
00700   UpdateHelper();
00701 
00702   for(int i=0; i<nLinks; i++){
00703     links[i].plambda = links[i].lambda;
00704     double t;
00705     double tk=links[i].mu*(1.1);
00706     
00707     if(niter){
00708       if(links[i].tlambda>tk)
00709     //t = pow((sqrt(links[i].lambda)+sqrt(links[i].mu+5))/2,2);
00710     t = ((links[i].lambda)+tk)/2;
00711       // t = exp((log(links[i].lambda)+log(links[i].mu+5))/2);
00712       else
00713     //t = pow((sqrt(links[i].tlambda)+sqrt(links[i].lambda))/2,2);
00714     t= ((links[i].tlambda)+(links[i].lambda))/2;
00715       // t = exp((log(links[i].tlambda)+log(links[i].lambda))/2);
00716     }
00717     else t = links[i].tlambda;
00718     links[i].lambda = t; // Update the lambda ..........
00719   }
00720 
00721 }  
00722 
00723 
00724 void Update2(){
00725 
00726   UpdateHelper();
00727 
00728   for(int i=0; i<nLinks; i++){
00729     links[i].plambda = links[i].lambda;
00730     links[i].lambda = (links[i].lambda + links[i].tlambda)/2;
00731   }
00732 }
00733 
00734 int allscaled(){
00735 
00736   //cout << nConnections;
00737 
00738   for(int i=0; i<nConnections; i++)
00739     if(!flows[i].is_sflow && !flows[i].scaled){
00740       cout << "Connection " << i << " not scaled as yet\n";
00741       return 0;
00742     }
00743 
00744   //cout << "All are scaled\n";
00745 
00746   return 1;
00747 
00748 }
00749   
00750 
00751 void Update3(int flag = 0){
00752 
00753 // flag = 1 means dont touch short flows in your scaling algo
00754 
00755 
00756   double maxtlambda = -1e7;
00757   int bneck = -1;
00758   int i;
00759 
00760   // 1st get set scaled var of all flows to 0
00761   for(i=0; i<nConnections; i++)
00762     flows[i].scaled = 0;
00763 
00764   // Calculate the tlambdas
00765   UpdateHelper();
00766 
00767   // Find out the link with the max throughput
00768 
00769   for(i=0; i<nLinks; i++){
00770     //cout << "after updatehelper link #" << i << " " << links[i].tlambda << "\n";
00771     if(links[i].tlambda>maxtlambda){
00772       bneck = i;
00773       maxtlambda = links[i].tlambda;
00774     }
00775   }
00776 
00777   cout << "bottleneck = " << bneck << sp << maxtlambda <<endl;
00778 
00779   double tk = links[bneck].mu*(1+links[bneck].drop)+5; 
00780   // We cant go above this tk ......
00781 
00782   while((maxtlambda > tk + 1) && ! allscaled()){
00783 
00784     cout << "Maxtlambda = " << maxtlambda << " bneck = " << bneck << endl;
00785 
00786     //    cout << "tk =  "<< tk << " maxlambda = " << maxtlambda << endl;
00787 
00788     // Now lets reduce this to tk
00789     assert(bneck>=0 && bneck<=nLinks);
00790     int i;
00791     for(i=0; i<links[bneck].nflows; i++){
00792  
00793      // For all the connections passing through this link
00794       int t = links[bneck].theflows[i]; // get a connection id
00795       // Now reduce its p_tput iff its not a short flow
00796       // For short flows we dont do scaling
00797       if(flag){
00798     if(!flows[t].is_sflow && !flows[t].scaled){
00799       flows[t].p_tput *= (tk)/maxtlambda;
00800       //cout << "Flow " << t << " getting scaled to  << " << flows[t].p_tput <<" \n";
00801       flows[t].scaled = 1; // we have scaled this flow already
00802     }
00803       }
00804       else
00805     flows[t].p_tput *= (tk)/maxtlambda;
00806       flows[t].scaled = 1; // we have scaled this flow already 
00807 
00808     }
00809 
00810     for (i=0; i<nLinks;i++){
00811       cout << "Link " << i << " tlambda = " << links[i].tlambda << endl;
00812     }
00813 
00814     //Char x =getchar();
00815 
00816     // Recalculate the flows' stats
00817     UpdateHelper(0);
00818 
00819     // Find out the link with the max throughput
00820     bneck = -1;
00821     maxtlambda = -1e7;
00822     for(i=0; i<nLinks; i++){
00823       if(links[i].tlambda>maxtlambda){
00824     bneck = i;
00825     maxtlambda = links[i].tlambda;
00826       }
00827     }    
00828 
00829 
00830     tk = links[bneck].mu*(1+links[bneck].drop)+5;
00831 
00832 
00833   }
00834 
00835   Update(0);
00836   cout << "Out of the converge loop\n";
00837     for (i =0; i<nLinks;i++){
00838       cout << "Link " << i << " tlambda = " << links[i].tlambda << endl;
00839     }
00840 
00841 }
00842 
00843 
00844 void newupdate(int niter){
00845 
00846   int i;
00847 
00848   // 1st init all unscaled tputs and cap
00849   for (i=0;i<nLinks;i++){
00850     links[i].uc = links[i].mu*(1.05);
00851     links[i].utput = 0;
00852   }
00853 
00854 
00855   // calc all the unscaled tputs and C set all short flows 
00856   // to be scaled already 
00857   for(i=0; i<nConnections; i++){
00858     if(flows[i].is_sflow)
00859       flows[i].scaled = 1;
00860     else 
00861       flows[i].scaled = 0;
00862     for(int j=0;j<nAdj[i];j++){
00863       if(flows[i].is_sflow)
00864     links[Adj[i][j]].uc -= flows[i].p_tput;
00865       else
00866     links[Adj[i][j]].utput += flows[i].p_tput;
00867     }
00868   }
00869 
00870   //  for(i=0; i<nLinks; i++ ){
00871   //cout << i << sp << links[i].uc << sp << links[i].utput << endl;
00872   //}
00873 
00874   double maxgamma; // most congested link
00875   int bneck;
00876   double t;
00877 
00878   bneck = -1;
00879   maxgamma = 0;
00880   for(i=0; i<nLinks; i++){
00881     if(links[i].uc){
00882       t=links[i].utput/links[i].uc;
00883       if(t > maxgamma){
00884     bneck = i;
00885     maxgamma = t;
00886       }
00887     }
00888   }    
00889 
00890   //cout << bneck << endl;
00891 
00892   //char c= getchar();
00893   /*
00894   for(i=0;i<nConnections;i++){
00895     cout << "connection" << sp << i << sp << "-"; 
00896     for(int j=0;j<nAdj[i];j++){
00897       cout << sp << Adj[i][j];
00898     }
00899     cout << endl;
00900   }
00901   */
00902   // c= getchar();
00903 
00904   while(bneck+1){
00905 
00906     // cout << "bneck = " << bneck << sp << links[bneck].uc << sp << links[bneck].utput << sp << maxgamma << sp << links[bneck].nflows <<endl;
00907 
00908     for(i=0; i<links[bneck].nflows; i++){
00909      // For all the connections passing through this link
00910       int t = links[bneck].theflows[i]; // get a connection id
00911       //     cout << i<< sp << t << sp ;
00912       // Now reduce its p_tput iff its not a short flow
00913       // For short flows we dont do scaling
00914       if(!flows[t].is_sflow && !flows[t].scaled){
00915     flows[t].p_tput /= maxgamma;
00916     //cout << "Flow " << t << " getting scaled to  << " << flows[t].p_tput;
00917     flows[t].scaled = 1; // we have scaled this flow already
00918     for(int j=0;j<nAdj[t];j++){
00919       // subtract this scaled throughout from all teh links that
00920       // have this flow. 
00921       links[Adj[t][j]].uc -= flows[t].p_tput;
00922       links[Adj[t][j]].utput -= flows[t].p_tput*maxgamma;
00923       // cout << sp << Adj[i][j];
00924     }
00925     //cout << endl;
00926       }
00927     }
00928     
00929     // cout << links[bneck].uc << sp << links[bneck].utput << endl;
00930     
00931     links[bneck].uc = 0;
00932 
00933     bneck = -1;
00934     maxgamma = 0;
00935     for(i=0; i<nLinks; i++){
00936       if(links[i].uc){
00937     t=links[i].utput/links[i].uc;
00938     if(t > maxgamma){
00939       bneck = i;
00940       maxgamma = t;
00941     }
00942       }
00943     } 
00944     /*
00945     c = getchar();
00946 
00947     for(i=0;i<nConnections;i++){
00948       cout << "connection" << sp << i << sp << "-"; 
00949       for(int j=0;j<nAdj[i];j++){
00950     cout << sp << Adj[i][j];
00951       }
00952       cout << endl;
00953       }*/
00954     
00955     // c=getchar();
00956 
00957   }
00958 
00959   Update(niter);
00960 
00961 }
00962 
00963 
00964   asim(){
00965     // cout << "Reached here\n";
00966   }
00967 
00968   void recv(Packet *, Handler * = 0){}
00969 
00970 };
00971 
00972 
00973 
00974 static class AsimClass : public TclClass {
00975 public:
00976   AsimClass(): TclClass("Asim"){ }
00977   TclObject * create(int, const char*const*) {
00978     return (new asim());
00979   }
00980 } class_asim;
00981 
00982 /*
00983 
00984 int main(int argc, char **argv) {
00985 
00986   int niter = 0;
00987 
00988   asim sim;
00989   sim.GetInputs(argc, argv);
00990   //  PrintResults();
00991   cout << "Read the input .... \n";
00992 
00993   for(int i=0; i<10; i++){
00994     sim.CalcLinkDelays(1);
00995     cout << "Calculated link delays ... \n";
00996     //    PrintResults();
00997 
00998     sim.CalcPerFlowDelays();
00999     cout << "Calculated per flow delays ... \n";
01000     cout << " ------------------------------\n";
01001     sim.newupdate(niter);
01002     //sim.PrintResults();
01003     cout << " ------------------------------\n"; 
01004   }
01005   sim.PrintResults();
01006 }
01007 
01008 
01009 */
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 
01018 
01019 
01020 

Generated on Tue Mar 6 16:47:43 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6