RIO.enque函数简要分析

#define DTYPE_NONE 0 /* ok, no drop */ #define DTYPE_FORCED 1 /* a "forced" drop */ #define DTYPE_UNFORCED 2 /* an "unforced" (random) drop */ void RIOQueue::enque(Packet* pkt) { hdr_flags* hf = hdr_flags::access(pkt); hdr_ip* iph = hdr_ip::access(pkt); if (priority_method_ == 1) { //priority_method_为1时采用的就是流标记法 hf->pri_ = iph->flowid(); //优先级标签就是流的ID } if (hf->pri_) { /* 处理in分组 */ ...... /*计算整个队列的平均长度,以及in队列的平均长度*/ edv_.v_ave = REDQueue::estimator(qib_ ? q_->byteLength() : q_->length(), m + 1, edv_.v_ave, edp_.q_w); edv_in_.v_ave = REDQueue::estimator(qib_ ? in_bcount_ : in_len_, m_in + 1, edv_in_.v_ave, edp_.q_w); //首先判断in队列是否要丢弃 if (in_qavg >= edp_in_.th_min && in_qlen > 1) { if ((!edp_in_.gentle && in_qavg >= edp_in_.th_max) || (edp_in_.gentle && in_qavg >= 2 * edp_in_.th_max)) { droptype = DTYPE_FORCED; } else if (edv_in_.old == 0) { /* * The average queue size has just crossed the * threshold from below to above "minthresh", or * from above "minthresh" with an empty queue to * above "minthresh" with a nonempty queue. */ edv_in_.count = 1; edv_in_.count_bytes = ch->size(); edv_in_.old = 1; } else if (drop_in_early(pkt)) { droptype = DTYPE_UNFORCED; } } else { /* No packets are being dropped. */ edv_in_.v_prob = 0.0; edv_in_.old = 0; } //瞬时队列长度大于队列限制的情况: if (qlen >= qlim) { // see if we've exceeded the queue size droptype = DTYPE_FORCED; } if (droptype == DTYPE_UNFORCED) { /* pick packet for ECN, which is dropping in this case */ Packet *pkt_to_drop = pickPacketForECN(pkt); /* * If the packet picked is different that the one that just * arrived, add it to the queue and remove the chosen packet. */ if (pkt_to_drop != pkt) { q_->enque(pkt); // printf( "in: qlen %d %d/n", q_->length(), length()); ++in_len_; in_bcount_ += ch->size(); q_->remove(pkt_to_drop); // printf("remove qlen %d %d/n",q_->length(),length()); if (hdr_flags::access(pkt_to_drop)->pri_) { in_bcount_ -= hdr_cmn::access(pkt_to_drop)->size(); --in_len_; } pkt = pkt_to_drop; /* ok 'cause pkt not needed anymore */ } // deliver to special "edrop" target, if defined if (de_drop_ != NULL) de_drop_->recv(pkt); else drop(pkt); } else { /* forced drop, or not a drop: first enqueue pkt */ q_->enque(pkt); // printf( "in: qlen %d %d/n", q_->length(), length()); ++in_len_; in_bcount_ += ch->size(); /* drop a packet if we were told to */ if (droptype == DTYPE_FORCED) { /* drop random victim or last one */ pkt = pickPacketToDrop(); q_->remove(pkt); // printf("remove qlen %d %d/n",q_->length(),length()); if (hdr_flags::access(pkt)->pri_) { in_bcount_ -= hdr_cmn::access(pkt)->size(); --in_len_; } drop(pkt); if (!ns1_compat_) { // bug-fix from Philip Liu, <[email protected]> edv_.count = 0; edv_.count_bytes = 0; edv_in_.count = 0; edv_in_.count_bytes = 0; } } } } else { /* out分组以及其他分组 */ ...... //out队列其实是没有的,真正和edp_out_.th_min对比的是整个队列的平均长度 if (qavg >= edp_out_.th_min && qlen > 1) { if (!edp_out_.gentle && qavg >= edp_out_.th_max || (edp_out_.gentle && qavg >= 2 * edp_out_.th_max)) { droptype = DTYPE_FORCED; // ? not sure, Yun } else if (edv_out_.old == 0) { /* * The average queue size has just crossed the * threshold from below to above "minthresh", or * from above "minthresh" with an empty queue to * above "minthresh" with a nonempty queue. */ edv_out_.count = 1; edv_out_.count_bytes = ch->size(); edv_out_.old = 1; } else if (drop_out_early(pkt)) { droptype = DTYPE_UNFORCED; // ? not sure, Yun } } else { edv_out_.v_prob = 0.0; edv_out_.old = 0; // explain } if (qlen >= qlim) { // see if we've exceeded the queue size droptype = DTYPE_FORCED; //need more consideration, Yun } if (droptype == DTYPE_UNFORCED) { /* pick packet for ECN, which is dropping in this case */ Packet *pkt_to_drop = pickPacketForECN(pkt); /* * If the packet picked is different that the one that just * arrived, add it to the queue and remove the chosen packet. */ if (pkt_to_drop != pkt) { q_->enque(pkt); //printf("out: qlen %d %d/n", q_->length(), length()); q_->remove(pkt_to_drop); //printf("remove qlen %d %d/n",q_->length(),length()); if (hdr_flags::access(pkt_to_drop)->pri_) { in_bcount_ -=hdr_cmn::access(pkt_to_drop)->size(); --in_len_; } pkt = pkt_to_drop;/* ok cause pkt not needed anymore */ } // deliver to special "edrop" target, if defined if (de_drop_ != NULL) de_drop_->recv(pkt); else drop(pkt); } else { /* forced drop, or not a drop: first enqueue pkt */ q_->enque(pkt); //printf("out: qlen %d %d/n", q_->length(), length()); /* drop a packet if we were told to */ if (droptype == DTYPE_FORCED) { /* drop random victim or last one */ pkt = pickPacketToDrop(); q_->remove(pkt); //printf("remove qlen %d %d/n",q_->length(),length()); if (hdr_flags::access(pkt)->pri_) { in_bcount_ -= hdr_cmn::access(pkt)->size(); --in_len_; } drop(pkt); } } } return; }

你可能感兴趣的:(null,Random,Access)