#include #include #include #include #include #include #include // Integration of Ashish's RED and asim #define _RED_ROUTER_MAIN_ #include "asim.h" #define sp " " // Optimization #include using namespace std; typedef struct c{ int no; // no of edges in the connection double delay; // total delay; double drop; // total drop prob double p_tput; double t; // The short flow stuff int is_sflow; // boolean to indicate whether there is a short flow double slambda; // The arrival rate of the connections int snopkts; // average of no of packets each short flow givies RedRouter * red; int scaled; // Whether this flow has been scaled or not }flow_stats; typedef struct n{ int red; // flag to notify whether its a red queue or not double pmin, pmax, minth, maxth; // RED parameters double lambda; // Arrival rate - Packets per second double plambda; // Temp lambda value. previous lambda double tlambda; double mu; // Consumption rate - Packets per second double prop; // Propagation delay of the link double qdelay; // Store the queuing delay for each link int buffer; // Total buffer double drop; // probability of drop int nflows; // Number of flows through this link vector theflows; // The flows through this link double scaled_lambda; double unscaled_lambda; double utput; // unscaled tput double uc; // unscaled capacity // RED RedRouter * redrouter; }link_stats; class asim { public: // data structures int nConnections; // Number of connections int K, MaxHops; // int nLinks; // Number of links int **Adj; // Stores the edge list of each connection int *nAdj; // Stores the no of edges per connection link_stats* links; flow_stats* flows; double min(double x, double y){ return (x 0); assert(nConnections >= 0); nAdj = new int[nConnections]; Adj = new int*[nConnections]; flows = new flow_stats[nConnections]; for (int i=0; i 0); // Allocate space for sotring lambdas and mus links = new link_stats[nLinks]; continue; } // Enter each route else if (!strcasecmp(t,"route")) { assert (nConnections > 0); assert (nLinks > 0); t = strtok(NULL," \t"); assert(t); int i = atoi(t); assert(i > 0 && i<= nConnections); i--; // We dunno whether this will be short flow specs flows[i].is_sflow = 0; // Lets assume its a normal flow flows[i].drop = 0; // Assume ideal case to start off flows[i].scaled = 0; // Not scaled as yet t = strtok(NULL," \t"); assert(t); nAdj[i] = atoi(t); assert(nAdj[i] > 0 && nAdj[i] <= nLinks); // We know how many links it will use Adj[i] = new int[nAdj[i]]; for (int j=0; j 0 && l <= nLinks); l--; Adj[i][j] = l; } if (MaxHops < nAdj[i]) MaxHops = nAdj[i]; t = strtok(NULL," \t"); // assert(t); // Short flows stuff if (t && !strcasecmp(t,"sh")) { // There are short flows on this route. flows[i].is_sflow = 1; // read the slambda t = strtok(NULL," \t"); assert(t); double tmp = atof(t); flows[i].slambda = tmp; // read the snopkts t = strtok(NULL," \t"); assert(t); int tmpi = atoi(t); flows[i].snopkts = tmpi; } // For cbr // Treat almost like a short flow! if (t && !strcasecmp(t,"cbr")) { // There are short flows on this route. flows[i].is_sflow = 2; // read the rate t = strtok(NULL," \t"); assert(t); double tmp = atof(t); flows[i].slambda = tmp; flows[i].snopkts = 1; } // Now, let us put the flows in persective // Insert the flow id trhough all the links int l_; for(int j=0;j 0); // Get the link number t = strtok(NULL," \t"); assert(t); int i = atoi(t); assert(i > 0 && i<= nLinks); i--; // Get the prop delay t = strtok(NULL," \t"); assert(t); double p = atof(t); assert(p>=0); links[i].prop = p; // Get the lambda for this link t = strtok(NULL," \t"); assert(t); p = atof(t); assert(p>=0); links[i].lambda = 0; links[i].tlambda = p; links[i].plambda = p; // Get the mu for this link t = strtok(NULL," \t"); assert(t); p = atof(t); assert(p>=0); links[i].mu = p; // Get the buffer for this link t = strtok(NULL," \t"); assert(t); int t1 = atoi(t); assert(t1>0); links[i].buffer = t1; // Check for RED Q or not t = strtok(NULL," \t"); if(t && !strcasecmp(t,"red")){ // must be a red queue // input red parameters // all parameters between 0 and 1 links[i].red=1; // get minth t = strtok(NULL," \t"); double dt = atof(t); //assert(dt>=0 && dt<=1); links[i].minth=dt; // get pmin t = strtok(NULL," \t"); dt = atof(t); //assert(dt>=0 && dt<=1); links[i].pmin=dt; // get maxth t = strtok(NULL," \t"); dt = atof(t); //assert(dt>=0 && dt<=1); links[i].maxth=dt; // get pmax t = strtok(NULL," \t"); dt = atof(t); //assert(dt>=0 && dt<=1); links[i].pmax=dt; // Invoke Ashish's RED module ... ignore pmin ..... links[i].redrouter = new RedRouter((int)links[i].minth, (int)links[i].maxth, links[i].pmax); assert(links[i].red); } else{ links[i].red=0; } links[i].nflows = 0; // init the num of flows continue; } assert(0); } // Check whether everything is all right assert (nConnections > 0); assert (nLinks > 0); for (int i=0; i 0); } double redFn(double minth, double pmin, double maxth, double pmax, double qlength){ assert(qlength>=0 && qlength<=1); assert(pmax>=0 && pmax<=1); assert(pmin>=0 && pmin<=1); assert(minth>=0 && minth<=1); assert(maxth>=0 && maxth<=1); assert(maxth>=minth); assert(pmax>pmin); double t; if(qlengthmaxth) return 1; return pmin + (qlength-minth)/(pmax-pmin); } void CalcLinkStats(int flag = 0){ // flag = 1 means enable RED // Calculate Link delays ... basically queuing delays for(int i=0; itk) //t = pow((sqrt(links[i].lambda)+sqrt(links[i].mu+5))/2,2); t = ((links[i].lambda)+tk)/2; // t = exp((log(links[i].lambda)+log(links[i].mu+5))/2); else //t = pow((sqrt(links[i].tlambda)+sqrt(links[i].lambda))/2,2); t= ((links[i].tlambda)+(links[i].lambda))/2; // t = exp((log(links[i].tlambda)+log(links[i].lambda))/2); } else t = links[i].tlambda; links[i].lambda = t; // Update the lambda .......... } } int allscaled(){ //cout << nConnections; for(int i=0; i maxgamma){ bneck = i; maxgamma = t; } } } while(bneck+1){ //cout << "bneck = " << bneck << sp << links[bneck].uc << sp << links[bneck].utput << sp << maxgamma << sp << links[bneck].nflows < maxgamma){ bneck = i; maxgamma = t; } } } } Update(niter); } asim(){ //cout << "Reached here\n"; } }; int main(int argc, char **argv) { int niter = 0; // error if usage is wrong if (argc != 2) { fprintf(stderr,"Usage: %s \n", argv[0]); exit(-1); } asim sim; sim.GetInputs(argv[1]); //sim.PrintResults(); //cout << "Read the input .... \n"; for(int i=0; i<3; i++){ sim.CalcLinkStats(1); //cout << "Calculated link delays ... \n"; sim.CalcPerFlowStats(); //cout << "Calculated per flow delays ... \n"; //cout << " ------------------------------\n"; sim.newupdate(niter); //sim.PrintResults(); //cout << " ------------------------------\n"; } sim.PrintResults(); }