📄 classifier-base.cc
字号:
//GMG commented out the above calc of burstStartTime, as it is incorrect. //Instead, we update the offset at each node, and schedule the DB at a //time offset after the arrival of the BHP at the node. Note that //offset is the difference between the time the DB is scheduled and the //BHP arrives at the node. The BHP leaves the node proc_time_ after it //arrives at the node. Note that for he first node, the DB is simply //scheduled at the offset time after the current time. In that //case, we need not alter hdr->offset_time_, as it was already set in //the sendBurst method of integrated_agent.cc. We replace the // above with the 3 lines below. //But note that hdr->offset_time_ is altered if FDLs are scheduled, at // all nodes; see below if (type_ == 1) //core node; note that for egress edge node, //the current function is not invoked hdr->offset_time_ += (hdr->FDL_delay_ - proc_time_ - hdr->tx_delay_); //GMG -- added if block below to check if the newly adjusted offset time is negative or zero. If so, the // BHP is dropped. Note that the burst will have already been dropped, as it will have already // have arrived in this node. Note also that the case of zero is degenerate; we don't know if the // burst event precedes or follows the BHP; we drop the BHP in this case as well. if( hdr->offset_time_ <= 0 ) { StatCollector &sc = StatCollector::instance(); sc.updateEntry( "BHPDROP", sc.getValue( "BHPDROP" ) + 1.0 ); drop(p); return; } double burstStartTime = curTime + hdr->offset_time_; fdl_count = hdr->fdl_count_; //GMG -- added passing of fdl_count to scheduler Schedule data = ls->schedData( burstStartTime, burstDur, fdl_count ); //GMG -- Adjust hdr->offset_time_ for any FDLs that are scheduled if (FS_.option_ == 1) // max # FDLs used per node hdr->offset_time_ += (double)(fdl_count) * (FS_.fdl_delay_); else if (FS_.option_ == 2) // max # FDLs used per path hdr->offset_time_ += (double)(fdl_count - hdr->fdl_count_) * (FS_.fdl_delay_); hdr->fdl_count_ = fdl_count; if( data.channel() < 0 ) { /* char str[200]; * sprintf( str, "Unable to schedule burst: %d in slot (%lf, %lf)", hdr->C_burst_id(), (burstStartTime * 1000.), (burstStartTime + burstDur) * 1000. ); * Debug::debug( str ); */ StatCollector &sc = StatCollector::instance(); //GMG - fixed following line; "BHPDROP" was written "BHPROP" sc.updateEntry( "BHPDROP", sc.getValue( "BHPDROP" ) + 1.0 ); //Packet::free( p ); //GMG -- changed the above from free to drop, to allow for trace objects drop(p); return; } Schedule control = ls->schedControl( bhpStartTime, bhpDur ); if( control.channel() < 0 ) { char str[200]; /* sprintf( str, "Unable to schedule BHP for burst: %d in slot (%lf, %lf)", hdr->C_burst_id(), bhpStartTime * 1000., (bhpStartTime + bhpDur) * 1000. ); Debug::debug( str ); */ StatCollector &sc = StatCollector::instance(); sc.updateEntry( "BHPDROP", sc.getValue( "BHPDROP" ) + 1.0 ); //Packet::free( p ); //GMG -- changed the above from free to drop, to allow for trace objects //GMG -- added restore of FDL scheduler state FS_.FdlSchedRestore(); drop(p); return; } // add the entry into the switch// ADDITIONAL NOTE: GMG -- Only need to add hash entry for data channel// schedule, and not control channel schedule. The reason is that the DCs// are scheduled when the BHP goes through the switch; when the DB arrives,// it needs to check that it was scheduled (and if not, it is dropped). It// searches the hash table for this. For BHPs, if they can't be scheduled// they are dropped immediately. double stime = data.startTime(); double etime = stime + burstDur; u_long chan = (u_long)data.channel(); lswitch.add( (unsigned long)hdr->C_burst_id_, (u_long)0, (u_long)chan, (double)stime, (double)etime, (double)etime ); // lswitch.add( (unsigned long)hdr->C_burst_id_, 0, 0, 0.0, 0.0, 0.0 );// Scheduler::instance().schedule( slot_[iph->daddr()], p, burstStartTime - curTime );//GMG -- the BHP should be scheduled to leave the core or edge// classifier (i.e., leave the node) at the BHP start time;// not the burst start time Scheduler::instance().schedule( slot_[iph->daddr()], p, bhpStartTime - curTime );}// Handle the functioning of a data-burstvoid BaseClassifier::handleDataBurst( Packet *p ) { if( p == NULL ) return; Debug::markTr( address_, p ); hdr_cmn *ch = hdr_cmn::access( p ); hdr_ip *iph = hdr_ip::access( p ); hdr_IPKT *hdr = hdr_IPKT::access( p ); if( ( ch->ptype() != PT_IPKT ) || ( iph->prio_ != 2 ) ) { Debug::debug( __FILE__, __LINE__,"Critical error: DataburstHandler reeived a non-burst ipkt" ); exit( -1 ); } HashEntry *he = lswitch.erase( (unsigned long) hdr->C_burst_id() ); if( he == NULL ) { /* critical error bhp is ahead of the burst or no scheduler found*/ /* char str[100]; sprintf( str, "Dropping burst: %d", hdr->C_burst_id() ); Debug::debug( str ); */ StatCollector &sc = StatCollector::instance(); sc.updateEntry( "BURSTDROP", sc.getValue( "BURSTDROP" ) + 1.0 );//GMG -- uncommented out this block of code that frees the TCP and ACK packets// in a data burst hdr_cmn* tcpch; int npkts = hdr->npkts(); Packet **tcp_pkt = (Packet**)p->accessdata(); while ( npkts--) { tcpch = hdr_cmn::access(*tcp_pkt); //GMG -- added TCPDROP, ACKDROP, and UDPDROP statistics collection if ( tcpch->ptype() == PT_TCP) { sc = StatCollector::instance(); sc.updateEntry( "TCPDROP", sc.getValue( "TCPDROP" ) + 1.0 ); } else if ( tcpch->ptype() == PT_ACK) { sc = StatCollector::instance(); sc.updateEntry( "ACKDROP", sc.getValue( "ACKDROP" ) + 1.0 ); } else if ( tcpch->ptype() == PT_UDP) { sc = StatCollector::instance(); sc.updateEntry( "UDPDROP", sc.getValue( "UDPDROP" ) + 1.0 ); } else if ( tcpch->ptype() == PT_CBR) { sc = StatCollector::instance(); sc.updateEntry( "CBRDROP", sc.getValue( "CBRDROP" ) + 1.0 ); } else if ( tcpch->ptype() == PT_EXP) { sc = StatCollector::instance(); sc.updateEntry( "EXPDROP", sc.getValue( "EXPDROP" ) + 1.0 ); } else if ( tcpch->ptype() == PT_PARETO) { sc = StatCollector::instance(); sc.updateEntry( "PARDROP", sc.getValue( "PARDROP" ) + 1.0 ); } //free( *tcp_pkt ); //GMG -- fixed this; originally was tcp_pkt // rather than *tcp_pkt //GMG -- further change -- changed from free to drop to allow for trace objects drop( *tcp_pkt ); tcp_pkt++; }//Uncommented out block of code ends here //Packet::free( p ); //GMG -- changed the above from free to drop, to allow for trace objects drop(p); return; } else { double curTime = Scheduler::instance().clock(); double sendTime = 0.0; if( he->arrTime >= curTime ) { /* Life is simple the sending time is the arrTime - curtime */ sendTime = he->arrTime - curTime; } else { /* Ok the burst came in late --*/ sendTime = 0.0; }// GMG the if block below is incorrect. The DB should always be transmitted// at sendTime. We comment the block out, and use the statement in the// else clause./* if( type_ == 0 ) { char str[100]; */ /* sprintf( str, "Node-type:%d Sending the burst:%ld at time: %lf, offsettime: %lf", type_, hdr->C_burst_id(), 1000. * (Scheduler::instance().clock() + BurstManager::offsettime()), 1000.* BurstManager::offsettime() ); Debug::debug( str ); *//* Scheduler::instance().schedule( slot_[iph->daddr()], p, BurstManager::offsettime() ); } else Scheduler::instance().schedule( slot_[iph->daddr()], p, sendTime );*/ Scheduler::instance().schedule( slot_[iph->daddr()], p, sendTime ); //GMG -- if this is an edge node, the first link recv method must // decrement the electronic buffer fill. Set ebuf_ind to 1 // and pointer to BaseClassifier for this case. For core // node, do nothing. if (type_ == 0) { hdr->ebuf_ind = 1; hdr->bc_ingress = this; } }}// definition of the base classifierstatic class BaseClassifierClass : public TclClass{ public: BaseClassifierClass() : TclClass( "Classifier/BaseClassifier" ) {} TclObject* create( int, const char*const* ) { return ( new BaseClassifier() ); }}class_BaseClassifier;//GMG -- added drop function for use with trace objectvoid BaseClassifier::drop(Packet* p){ if (drop_ != 0) drop_->recv(p); else Packet::free(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -