📄 dsred.cc
字号:
while ((i < numQueues_) && ((redq_[qToDq].getRealLength() == 0) || ((queueAvgRate[qToDq] > queueMaxRate[qToDq]) && queueMaxRate[qToDq]))) { i++; qToDq = i; } if (i == numQueues_) { i = qToDq = 0; while ((i < numQueues_) && (redq_[qToDq].getRealLength() == 0)) { qToDq = ((qToDq + 1) % numQueues_); i++; } } }} /*------------------------------------------------------------------------------void lookupPHBTable(int codePt, int* queue, int* prec) Assigns the queue and prec parameters values corresponding to a given code point. The code point is assumed to be present in the PHB table. If it is not, an error message is outputted and queue and prec are undefined.------------------------------------------------------------------------------*/void dsREDQueue::lookupPHBTable(int codePt, int* queue, int* prec) { for (int i = 0; i < phbEntries; i++) { if (phb_[i].codePt_ == codePt) { *queue = phb_[i].queue_; *prec = phb_[i].prec_; return; } } printf("ERROR: No match found for code point %d in PHB Table.\n", codePt);}/*------------------------------------------------------------------------------void addPHBEntry(int codePt, int queue, int prec) Add a PHB table entry. (Each entry maps a code point to a queue-precedencepair.)------------------------------------------------------------------------------*/void dsREDQueue::addPHBEntry(int codePt, int queue, int prec) { if (phbEntries == MAX_CP) { printf("ERROR: PHB Table size limit exceeded.\n"); } else { phb_[phbEntries].codePt_ = codePt; phb_[phbEntries].queue_ = queue; phb_[phbEntries].prec_ = prec; stats.valid_CP[codePt] = 1; phbEntries++; }}/*------------------------------------------------------------------------------void addPHBEntry(int codePt, int queue, int prec) Add a PHB table entry. (Each entry maps a code point to a queue-precedencepair.)------------------------------------------------------------------------------*/double dsREDQueue::getStat(int argc, const char*const* argv) { if (argc == 3) { if (strcmp(argv[2], "drops") == 0) return (stats.drops*1.0); if (strcmp(argv[2], "edrops") == 0) return (stats.edrops*1.0); if (strcmp(argv[2], "pkts") == 0) return (stats.pkts*1.0); } if (argc == 4) { if (strcmp(argv[2], "drops") == 0) return (stats.drops_CP[atoi(argv[3])]*1.0); if (strcmp(argv[2], "edrops") == 0) return (stats.edrops_CP[atoi(argv[3])]*1.0); if (strcmp(argv[2], "pkts") == 0) return (stats.pkts_CP[atoi(argv[3])]*1.0); } return -1.0;}/*------------------------------------------------------------------------------void setNumPrec(int prec) Sets the current number of drop precendences. The number of precedences isthe number of virtual queues per physical queue.------------------------------------------------------------------------------*/void dsREDQueue::setNumPrec(int prec) { int i; if (prec > MAX_PREC) { printf("ERROR: Cannot declare more than %d prcedence levels (as defined by MAX_PREC)\n",MAX_PREC); } else { numPrec = prec; for (i = 0; i < MAX_QUEUES; i++) redq_[i].numPrec = numPrec; }}/*------------------------------------------------------------------------------void setMREDMode(const char* mode) sets up the average queue accounting mode.----------------------------------------------------------------------------*/void dsREDQueue::setMREDMode(const char* mode, const char* queue) { int i; mredModeType tempMode; if (strcmp(mode, "RIO-C") == 0) tempMode = rio_c; else if (strcmp(mode, "RIO-D") == 0) tempMode = rio_d; else if (strcmp(mode, "WRED") == 0) tempMode = wred; else if (strcmp(mode, "DROP") == 0) tempMode = dropTail; else { printf("Error: MRED mode %s does not exist\n",mode); return; } if (!queue) for (i = 0; i < MAX_QUEUES; i++) redq_[i].mredMode = tempMode; else redq_[atoi(queue)].mredMode = tempMode;}/*------------------------------------------------------------------------------void printPHBTable() Prints the PHB Table, with one entry per line.------------------------------------------------------------------------------*/void dsREDQueue::printPHBTable() { printf("PHB Table:\n"); for (int i = 0; i < phbEntries; i++) printf("Code Point %d is associated with Queue %d, Precedence %d\n", phb_[i].codePt_, phb_[i].queue_, phb_[i].prec_); printf("\n");}/*------------------------------------------------------------------------------void printStats() An output method that may be altered to assist debugging.------------------------------------------------------------------------------*/void dsREDQueue::printStats() { printf("\nPackets Statistics\n"); printf("=======================================\n"); printf(" CP TotPkts TxPkts ldrops edrops\n"); printf(" -- ------- ------ ------ ------\n"); printf("All %8ld %8ld %8ld %8ld\n",stats.pkts,stats.pkts-stats.drops-stats.edrops,stats.drops,stats.edrops); for (int i = 0; i < MAX_CP; i++) if (stats.pkts_CP[i] != 0) printf("%3d %8ld %8ld %8ld %8ld\n",i,stats.pkts_CP[i],stats.pkts_CP[i]-stats.drops_CP[i]-stats.edrops_CP[i],stats.drops_CP[i],stats.edrops_CP[i]);}void dsREDQueue::printWRRcount() { int i; for (i = 0; i < numQueues_; i++){ printf("%d: %d %d %d.\n", i, slicecount[i],pktcount[i],queueWeight[i]); }}/*------------------------------------------------------------------------------void setSchedularMode(int schedtype) sets up the schedular mode.----------------------------------------------------------------------------*/void dsREDQueue::setSchedularMode(const char* schedtype) { if (strcmp(schedtype, "RR") == 0) schedMode = schedModeRR; else if (strcmp(schedtype, "WRR") == 0) schedMode = schedModeWRR; else if (strcmp(schedtype, "WIRR") == 0) schedMode = schedModeWIRR; else if (strcmp(schedtype, "WFQ") == 0) schedMode = schedModeWFQ; else if (strcmp(schedtype, "PRI") == 0) schedMode = schedModePRI; else printf("Error: Scheduler type %s does not exist\n",schedtype);}/*------------------------------------------------------------------------------void addQueueWeights(int queueNum, int weight) An input method to set the individual Queue Weights.----------------------------------------------------------------------------*/void dsREDQueue::addQueueWeights(int queueNum, int weight) { if(queueNum < MAX_QUEUES){ queueWeight[queueNum]=weight; } else { printf("The queue number is out of range.\n"); }}/*void setQSize(int queueNum, int qMaxSize)Sets phisical queue size*/void dsREDQueue::setQSize(int queueNum, int qMaxSize) { if(queueNum < MAX_QUEUES) { redq_[queueNum].qlim = qMaxSize; } else { printf("The queue number is out of range.\n"); }}/*------------------------------------------------------------------------------void addQueueRate(int queueNum, int rate) An input method to set the individual Queue Max Rates for Priority Queueing.----------------------------------------------------------------------------*/void dsREDQueue::addQueueRate(int queueNum, int rate) { if(queueNum < MAX_QUEUES){ queueMaxRate[queueNum]=(double)rate/8.0; } else { printf("The queue number is out of range.\n"); }}/*------------------------------------------------------------------------------int command(int argc, const char*const* argv) Commands from the ns file are interpreted through this interface.------------------------------------------------------------------------------*/int dsREDQueue::command(int argc, const char*const* argv){ if (strcmp(argv[1], "configQ") == 0) { redq_[atoi(argv[2])].config(atoi(argv[3]), argv); return(TCL_OK); } if (strcmp(argv[1], "addPHBEntry") == 0) { addPHBEntry(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); return (TCL_OK); } if (strcmp(argv[1], "meanPktSize") == 0) { for (int i = 0; i < MAX_QUEUES; i++) redq_[i].setMPS(atoi(argv[2])); return(TCL_OK); } if (strcmp(argv[1], "setNumPrec") == 0) { setNumPrec(atoi(argv[2])); return(TCL_OK); } if (strcmp(argv[1], "getAverage") == 0) { Tcl& tcl = Tcl::instance(); tcl.resultf("%f", redq_[atoi(argv[2])].getWeightedLength()); return(TCL_OK); } if (strcmp(argv[1], "setQSize") == 0) { setQSize(atoi(argv[2]),atoi(argv[3])); return(TCL_OK); } if (strcmp(argv[1], "getStat") == 0) { Tcl& tcl = Tcl::instance(); tcl.resultf("%f", getStat(argc,argv)); return(TCL_OK); } if (strcmp(argv[1], "getCurrent") == 0) { Tcl& tcl = Tcl::instance(); tcl.resultf("%f", redq_[atoi(argv[2])].getRealLength()*1.0); return(TCL_OK); } if (strcmp(argv[1], "printStats") == 0) { printStats(); return (TCL_OK); } if (strcmp(argv[1], "printWRRcount") == 0) { printWRRcount(); return (TCL_OK); } if (strcmp(argv[1], "printPHBTable") == 0) { printPHBTable(); return (TCL_OK); } if (strcmp(argv[1], "link") == 0) { Tcl& tcl = Tcl::instance(); LinkDelay* del = (LinkDelay*) TclObject::lookup(argv[2]); if (del == 0) { tcl.resultf("RED: no LinkDelay object %s", argv[2]); return(TCL_ERROR); } link_ = del; return (TCL_OK); } if (strcmp(argv[1], "early-drop-target") == 0) { Tcl& tcl = Tcl::instance(); NsObject* p = (NsObject*)TclObject::lookup(argv[2]); if (p == 0) { tcl.resultf("no object %s", argv[2]); return (TCL_ERROR); } de_drop_ = p; return (TCL_OK); } if (strcmp(argv[1], "setSchedularMode") == 0) { setSchedularMode(argv[2]); return(TCL_OK); } if (strcmp(argv[1], "setMREDMode") == 0) { if (argc == 3) setMREDMode(argv[2],0); else setMREDMode(argv[2],argv[3]); return(TCL_OK); } if (strcmp(argv[1], "addQueueWeights") == 0) { addQueueWeights(atoi(argv[2]), atoi(argv[3])); return(TCL_OK); } if (strcmp(argv[1], "addQueueRate") == 0) { addQueueRate(atoi(argv[2]), atoi(argv[3])); return(TCL_OK); } return(Queue::command(argc, argv));}void dsREDQueue::handle(Event *e) { int queue; double now; now = Scheduler::instance().clock();//update virtual time v_time=v_time+(now-last_vt_update)/sum; last_vt_update=now;//extract packet in GPS system queue=GPS_queueID_l.get_data_min(); GPS_queueID_l.extract();//update B and sum if( (--B[queue]) == 0) sum=sum-queueWeight[queue]; if ( fabs(sum) < 1.0/1000.0 ) sum=0; if(sum==0) { idle=1; for(int i=0;i < MAX_QUEUES;i++) finish_t[i]=0; }// if GPS is not idle, schedule next GPS departure delete e; if(!idle) scheduleWFQ(); else wfq_event=0;}void dsREDQueue::scheduleWFQ() { wfq_event=new Event(); // implements last unnumbered formula in // "Virtual Time Implemetation" paragraph // "GPS Approach to flow...:single node case" Parekh e Gallager double tmp=(GPS_queueID_l.get_key_min()-v_time)*sum; // following line is there to recover errors due to finite precision if (tmp<0) tmp=0; Scheduler::instance().schedule((Handler *)this,wfq_event,tmp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -