⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 red.cpp

📁 我自己写的 RED改进算法的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1990-1997 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the Computer Systems *	Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * Here is one set of parameters from one of Sally's simulations * (this is from tcpsim, the older simulator): *  * ed [ q_weight=0.002 thresh=5 linterm=30 maxthresh=15 *         mean_pktsize=500 dropmech=random-drop queue-size=60 *         plot-file=none bytes=false doubleq=false dqthresh=50  *	   wait=true ] *  * 1/"linterm" is the max probability of dropping a packet.  * There are different options that make the code * more messy that it would otherwise be.  For example, * "doubleq" and "dqthresh" are for a queue that gives priority to *   small (control) packets,  * "bytes" indicates whether the queue should be measured in bytes  *   or in packets,  * "dropmech" indicates whether the drop function should be random-drop  *   or drop-tail when/if the queue overflows, and  *   the commented-out Holt-Winters method for computing the average queue  *   size can be ignored. * "wait" indicates whether the gateway should wait between dropping *   packets. */#ifndef lintstatic const char rcsid[] =    "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/red.cc,v 1.55 2000/11/17 22:10:33 ratul Exp $ (LBL)";#endif#include <math.h>#include <sys/types.h>#include "config.h"#include "template.h"#include "random.h"#include "flags.h"#include "delay.h"#include "red.h"#include "connector.h"   //add header #include "packet.h"#include "tbf.h"static class REDClass : public TclClass {public:	REDClass() : TclClass("Queue/RED") {}	TclObject* create(int argc, const char*const* argv) {		//printf("creating RED Queue. argc = %d\n", argc);				//mod to enable RED to take arguments		if (argc==5) 			return (new REDQueue(argv[4]));		else			return (new REDQueue("Drop"));	}} class_red;/* Strangely this didn't work.  * Seg faulted for child classes.REDQueue::REDQueue() { 	REDQueue("Drop");}*//* * modified to enable instantiation with special Trace objects - ratul */REDQueue::REDQueue(const char * trace) : link_(NULL), bcount_(0), de_drop_(NULL), EDTrace(NULL),	tchan_(0), idle_(1), first_reset_(1){	//	printf("Making trace type %s\n", trace);	if (strlen(trace) >=20) {		printf("trace type too long - allocate more space to traceType in red.h and recompile\n");		exit(0);	}	strcpy(traceType, trace);	bind_bool("bytes_", &edp_.bytes);	    // boolean: use bytes?	bind_bool("queue_in_bytes_", &qib_);	    // boolean: q in bytes?	//	_RENAMED("queue-in-bytes_", "queue_in_bytes_");	bind("thresh_", &edp_.th_min);		    // minthresh	bind("maxthresh_", &edp_.th_max);	    // maxthresh	bind("mean_pktsize_", &edp_.mean_pktsize);  // avg pkt size	bind("q_weight_", &edp_.q_w);		    // for EWMA	bind_bool("wait_", &edp_.wait);	bind("linterm_", &edp_.max_p_inv);	bind_bool("setbit_", &edp_.setbit);	    // mark instead of drop	bind_bool("gentle_", &edp_.gentle);         // increase the packet						    // drop prob. slowly						    // when ave queue						    // exceeds maxthresh	bind_bool("drop_tail_", &drop_tail_);	    // drop last pkt	//	_RENAMED("drop-tail_", "drop_tail_");	bind_bool("drop_front_", &drop_front_);	    // drop first pkt	//	_RENAMED("drop-front_", "drop_front_");		bind_bool("drop_rand_", &drop_rand_);	    // drop pkt at random	//	_RENAMED("drop-rand_", "drop_rand_");	bind_bool("ns1_compat_", &ns1_compat_);	    // ns-1 compatibility	//	_RENAMED("ns1-compat_", "ns1_compat_");	bind("ave_", &edv_.v_ave);		    // average queue sie	bind("prob1_", &edv_.v_prob1);		    // dropping probability	bind("curq_", &curq_);			    // current queue size		q_ = new PacketQueue();			    // underlying queue	pq_ = q_;	reset();#ifdef notdef	print_edp();	print_edv();#endif	}void REDQueue::reset(){	/*	 * If queue is measured in bytes, scale min/max thresh	 * by the size of an average packet (which is specified by user).	 */	        if (qib_ && first_reset_ == 1) {                //printf ("edp_.th_min: %5.3f \n", edp_.th_min);                edp_.th_min *= edp_.mean_pktsize;                  edp_.th_max *= edp_.mean_pktsize;                //printf ("edp_.th_min: %5.3f \n", edp_.th_min);                first_reset_ = 0;        }	/*	 * Compute the "packet time constant" if we know the	 * link bandwidth.  The ptc is the max number of (avg sized)	 * pkts per second which can be placed on the link.	 * The link bw is given in bits/sec, so scale mean psize	 * accordingly.	 */	 	if (link_)		edp_.ptc = link_->bandwidth() /			(8. * edp_.mean_pktsize);	edv_.v_ave = 0.0;	edv_.v_slope = 0.0;	edv_.count = 0;	edv_.count_bytes = 0;	edv_.old = 0;	edv_.v_a = 1 / (edp_.th_max - edp_.th_min);	edv_.v_b = - edp_.th_min / (edp_.th_max - edp_.th_min);	if (edp_.gentle) {		edv_.v_c = ( 1.0 - 1 / edp_.max_p_inv ) / edp_.th_max;		edv_.v_d = 2 / edp_.max_p_inv - 1.0;	}	idle_ = 1;	if (&Scheduler::instance() != NULL)		idletime_ = Scheduler::instance().clock();	else		idletime_ = 0.0; /* sched not instantiated yet */		if (debug_) 		printf("Doing a queue reset\n");	Queue::reset();	if (debug_) 		printf("Done queue reset\n");	bcount_ = 0;}/* * Compute the average queue size. * Nqueued can be bytes or packets. */double REDQueue::estimator(int nqueued, int m, double ave, double q_w){	double new_ave, old_ave;	new_ave = ave;	while (--m >= 1) {		old_ave = new_ave;		new_ave *= 1.0 - q_w;	}	old_ave = new_ave;	new_ave *= 1.0 - q_w;	new_ave += q_w * nqueued;	return new_ave;}void REDQueue::reset_cou(){	cou_grn = 0;	cou_red = 0;}/* * Return the next packet in the queue for transmission. */Packet* REDQueue::deque(){	Packet *p;	p = q_->deque();	if (p != 0) {		idle_ = 0;		bcount_ -= hdr_cmn::access(p)->size();	} else {		idle_ = 1;		// deque() may invoked by Queue::reset at init		// time (before the scheduler is instantiated).		// deal with this case		if (&Scheduler::instance() != NULL)			idletime_ = Scheduler::instance().clock();		else			idletime_ = 0.0;	}	return (p);}//modify  discard  cursor positon double REDQueue::calculate_pos(double th_max, double th_min, double para_modi) {  	double position; 	position = th_max - para_modi*(th_max - th_min);   return position ; }///* * Calculate the drop probability.*/doubleREDQueue::calculate_p(double v_ave, double th_max, int gentle, double v_a, 	double v_b, double v_c, double v_d, double max_p_inv){	double p;	if (gentle && v_ave >= th_max) {		// p ranges from max_p to 1 as the average queue		// size ranges from th_max to twice th_max 		p = v_c * v_ave + v_d;	} else {		// p ranges from 0 to max_p as the average queue		// size ranges from th_min to th_max 		p = v_a * v_ave + v_b;		p /= max_p_inv;	}	if (p > 1.0)		p = 1.0;	return p;} // Make uniform instead of geometric interdrop periods.doubleREDQueue::modify_p(double p, int count, int count_bytes, int bytes,    int mean_pktsize, int wait, int size){	double count1 = (double) count;	if (bytes)		count1 = (double) (count_bytes/mean_pktsize);	if (wait) {		if (count1 * p < 1.0)			p = 0.0;		else if (count1 * p < 2.0)			p /= (2 - count1 * p);		else			p = 1.0;	} else {		if (count1 * p < 1.0)			p /= (1.0 - count1 * p);		else			p = 1.0;	}	if (bytes && p < 1.0) {		p = p * size / mean_pktsize;	}	if (p > 1.0)		p = 1.0; 	return p;} /* * should the packet be dropped/marked due to a probabilistic drop? */intREDQueue::drop_early(Packet* pkt){	hdr_cmn* ch = hdr_cmn::access(pkt);	/* edv_.v_prob1 = calculate_p(edv_.v_ave, edp_.th_max, edp_.gentle,   	  edv_.v_a, edv_.v_b, edv_.v_c, edv_.v_d, edp_.max_p_inv);	edv_.v_prob = modify_p(edv_.v_prob1, edv_.count, edv_.count_bytes,	  edp_.bytes, edp_.mean_pktsize, edp_.wait, ch->size()); */  pos_dis = calculate_pos(edp_.th_max,  edp_.th_min, para_modi);    if (pos_dis < edv_.v_ave)   	{  		edv_.count = 0;		edv_.count_bytes = 0;		hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));  		if (edp_.setbit && hf->ect() && edv_.v_ave < edp_.th_max) {			hf->ce() = 1; 	// mark Congestion Experienced bit			return (0);	// no drop		} else {			return (1);	// drop		}	}	return (0);			// no DROP/mark}	// drop probability is computed, pick random number and act	/*double u = Random::uniform();	if (u <= edv_.v_prob) {		// DROP or MARK		edv_.count = 0;		edv_.count_bytes = 0;		hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));		if (edp_.setbit && hf->ect() && edv_.v_ave < edp_.th_max) {			hf->ce() = 1; 	// mark Congestion Experienced bit			return (0);	// no drop		} else {			return (1);	// drop		}	}	return (0);			// no DROP/mark}*/double REDQueue::getupdatedtokens(void){	double now=Scheduler::instance().clock();		tokens_ += (now-lastupdatetime_)*rate_;	if (tokens_ > bucket_)		tokens_=bucket_;	lastupdatetime_ = Scheduler::instance().clock();	return tokens_;}/* * Pick packet for early congestion notification (ECN). This packet is then * marked or dropped. Having a separate function do this is convenient for * supporting derived classes that use the standard RED algorithm to compute * average queue size but use a different algorithm for choosing the packet for  * ECN notification. */Packet*REDQueue::pickPacketForECN(Packet* pkt){	return pkt; /* pick the packet that just arrived */}/* * Pick packet to drop. Having a separate function do this is convenient for * supporting derived classes that use the standard RED algorithm to compute * average queue size but use a different algorithm for choosing the victim. */Packet*REDQueue::pickPacketToDrop() {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -