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

📄 ns-queue.tcl

📁 对IEEE 802.11e里的分布式信道接入算法EDCA进行改进
💻 TCL
字号:
## Copyright (c) 1996-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 MASH Research# 	Group at the University of California Berkeley.# 4. Neither the name of the University nor of the Research Group 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.## @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcl/lib/ns-queue.tcl,v 1.20 2000/07/20 00:41:19 ratul Exp $### This file contains auxillary support for CBQ and CBQ links, and# some embryonic stuff for Queue Monitors. -KF### CBQ### set up the baseline CBQ or CBQ/WRR object#	baseline object contains only an empty classifier#	and the scheduler (CBQ or CBQ/WRR) object itself## After initialized, the structure is as follows:###	head_-> (classifier)#	queue_-> (cbq) ==> link_#	drophead_ -> (connector) ==> nullAgent## == is data flow# -- is a pointer reference#Class CBQLink -superclass SimpleLinkCBQLink instproc init { src dst bw delay q cl {lltype "DelayLink"} } {        $self next $src $dst $bw $delay $q $lltype ; # SimpleLink ctor        $self instvar head_ queue_ link_	$self instvar  classifier_	; # not found in a SimpleLink#	$self instvar  drophead_ ; # not found in a SimpleLink	$queue_ link $link_ ; # queue_ set by SimpleLink ctor, CBQ needs $link_        set classifier_ $cl	$head_ target $classifier_#	set drophead_ [new Connector]#	$drophead_ target [[Simulator instance] set nullAgent_]	#	# the following is merely to inject 'algorithm_' in the	# $queue_ class' name space.  It is not used in ns-2, but	# is needed here for the compat code to recognize that	# 'set algorithm_ foo' commands should work	#	set defalg [Queue/CBQ set algorithm_]	$queue_ set algorithm_ $defalg	# this part actually sets the default	$queue_ algorithm $defalg}## set up a trace.  Calling the SimpleLink version is harmless, but doesn't# do exactly what we need##CBQLink instproc trace { ns f } {#	$self next $ns $f#	$self instvar drpT_ drophead_#	set nxt [$drophead_ target]#	$drophead_ target $drpT_#	$drpT_ target $nxt#}## set up monitors.  Once again, the base version is close, but not# exactly what's needed##CBQLink instproc attach-monitors { isnoop osnoop dsnoop qmon } {#	$self next $isnoop $osnoop $dsnoop $qmon#	$self instvar drophead_#	set nxt [$drophead_ target]#	$drophead_ target $dsnoop#	$dsnoop target $nxt#}CBQLink instproc classifier {} {	$self instvar classifier_	return $classifier_}### for flow-id based classification, bind c# CBQClass to a given flow id # (or range)## OTcl usage:# 	bind $cbqclass id#    		or# 	bind $cbqclass idstart idend## these use flow id's as id's#CBQLink instproc bind args {	# this is to perform '$cbqlink bind $cbqclass id'	# and '$cbqlink insert $cbqclass bind $cbqclass idstart idend'	$self instvar classifier_	set nargs [llength $args]	set cbqcl [lindex $args 0]	set a [lindex $args 1]	if { $nargs == 3 } {		set b [lindex $args 2]	} else {		set b $a	}	# bind the class to the flow id's [a..b]	while { $a <= $b } {		# first install the class to get its slot number		# use the flow id as the hash bucket		set slot [$classifier_ installNext $cbqcl]		$classifier_ set-hash auto 0 0 $a $slot		incr a	}}## insert the class into the link# each class will have an associated queue# we must create a set of snoop qs with an associated qmon# which cbq uses to monitor demand.  The qmon may either be# given, or defaults to just a QueueMonitor type.## Otcl usage:#	insert $cbqclass#	insert $cbqclass $qmon## the two different usages are used to make backward compat with# ns-1 easier, since in ns-2, insert was in c++## general idea:#  pkt--> Classifier --> CBQClass --> snoopin --> qdisc --> snoopout --> CBQ#CBQLink instproc insert args {	# queue_ refers to the cbq object	$self instvar queue_ drophead_ link_	set nargs [llength $args]	set cbqcl [lindex $args 0]	set qdisc [$cbqcl qdisc]	if { $nargs == 1 } {		set qmon [new QueueMonitor]	} else {		set qmon [lindex $args 1]	}	# qdisc can be null for internal classes	if { $qmon == "" } {		error "CBQ requires a q-monitor for class $cbqcl"	}	if { $qdisc != "" } {		# create in, out, and drop snoop queues		# and attach them to the same monitor		# this is used by CBQ to assess demand		# (we don't need bytes/pkt integrator or stats here)		set in [new SnoopQueue/In]		set out [new SnoopQueue/Out]		set drop [new SnoopQueue/Drop]		$in set-monitor $qmon		$out set-monitor $qmon		$drop set-monitor $qmon		# output of cbqclass -> snoopy inq		$in target $qdisc		$cbqcl target $in		# drop from qdisc -> snoopy dropq		# snoopy dropq's target is overall cbq drop target		$qdisc drop-target $drop		$drop target $drophead_		# output of queue -> snoopy outq		# output of snoopy outq is cbq		$qdisc target $out		$out target $queue_		# tell this class about its new queue monitor		$cbqcl qmon $qmon	}	$cbqcl instvar maxidle_	if { $maxidle_ == "auto" } {		$cbqcl automaxidle [$link_ set bandwidth_] \			[$queue_ set maxpkt_]		set maxidle_ [$cbqcl set maxidle_]	}	$cbqcl maxidle $maxidle_	# tell cbq about this class	# (this also tells the cbqclass about the cbq)	$queue_ insert-class $cbqcl}## procedures on a cbq class#CBQClass instproc init {} {	$self next	$self instvar automaxidle_gain_	set automaxidle_gain_ [$class set automaxidle_gain_]}CBQClass instproc automaxidle { linkbw maxpkt } {	$self instvar automaxidle_gain_ maxidle_	$self instvar priority_	set allot [$self allot]	set g $automaxidle_gain_	set n [expr 8 * $priority_]	if { $g == 0 || $allot == 0 || $linkbw == 0 } {		set maxidle_ 0.0		return	}	set gTOn [expr pow($g, $n)]	set first [expr ((1/$allot) - 1) * (1-$gTOn) / $gTOn ]	set second [expr (1 - $g)]	set t [expr ($maxpkt * 8.0)/$linkbw]	if { $first > $second } {		set maxidle_ [expr $t * $first]	} else {		set maxidle_ [expr $t * $second]	}	return $maxidle_}CBQClass instproc setparams { parent okborrow allot maxidle prio level xdelay } {        $self allot $allot	$self parent $parent	$self set okborrow_ $okborrow        $self set maxidle_ $maxidle        $self set priority_ $prio        $self set level_ $level        $self set extradelay_ $xdelay        return $self}## insert a queue into a CBQ class:#	arrange for the queue to initally be blocked#	and for it to block when resumed#	(provides flow control on the queue)CBQClass instproc install-queue q {	$q set blocked_ true	$q set unblock_on_resume_ false	$self qdisc $q}## QueueMonitor#QueueMonitor instproc reset {} {	$self instvar size_ pkts_	$self instvar parrivals_ barrivals_	$self instvar pdepartures_ bdepartures_	$self instvar pdrops_ bdrops_	# don't reset size_ and pkts_ here	# because they are not cumulative measurements	# the way the following values are	set parrivals_ 0	set barrivals_ 0	set pdepartures_ 0	set bdepartures_ 0	set pdrops_ 0	set bdrops_ 0	set bint [$self get-bytes-integrator]	if { $bint != "" } {		$bint reset	}	set pint [$self get-pkts-integrator]	if { $pint != "" } {		$pint reset	}	set samp [$self get-delay-samples]	if { $samp != "" } {		$samp reset	}}QueueMonitor/ED instproc reset {} {	$self next	$self instvar epdrops_ ebdrops_	set epdrops_ 0	set ebdrops_ 0}Class AckReconsClass -superclass AgentAckReconsControllerClass instproc demux { src dst } {	$self instvar reconslist_ queue_	set addr $src:$dst	if { ![info exists reconslist_($addr)] } {		set recons [new Agent/AckReconsClass $src $dst]		$recons target $queue_		set reconslist_($addr) $recons	}	# return an ack reconstructor object	return $reconslist_($addr)}# Calculate number and spacing of acks to be sent# deltaAckThresh_ = threshold after which reconstructor kicks in# ackInterArr_ = estimate of arrival rate of acks ("counting process")# ackSpacing_ = duration in time between acks sent by reconstructor# delack_ = generate an ack at least every delack_ acks at reconstructorAgent/AckReconsClass instproc spacing { ack } {	$self instvar ackInterArr_ ackSpacing_ delack_ \			lastAck_ lastRealAck_ lastRealTime_ adaptive_ size_	global ns		set deltaTime [expr [$ns now] - $lastRealTime_]	set deltaAck [expr $ack - $lastAck_]	if {$adaptive_} {		set bw [expr $deltaAck*$size_/$deltaTime]		set ackSpacing_ $ackInterArr_		if { $deltaAck > 0 } {#			set ackSpacing_ [expr $ackInterArr_*$delack_/$deltaAck]		}	} else {		set deltaT [expr $deltaTime / ($deltaAck/$delack_ +1)]		set ackSpacing_ $deltaT	}}# Estimate rate at which acks are arrivingAgent/AckReconsClass instproc ackbw {ack time} {	$self instvar ackInterArr_ lastRealTime_ lastRealAck_ alpha_	set sample [expr $time - $lastRealTime_]	# EWMA	set ackInterArr_ [expr $alpha_*$sample + (1-$alpha_)*$ackInterArr_]}Class Classifier/Hash/Fid/FQ -superclass Classifier/Hash/FidClassifier/Hash/Fid/FQ instproc unknown-flow { src dst fid } {	$self instvar fq_	$fq_ new-flow $src $dst $fid}Class FQLink -superclass SimpleLinkFQLink instproc init { src dst bw delay q } {	$self next $src $dst $bw $delay $q	$self instvar link_ queue_ head_ toNode_ ttl_ classifier_ \		nactive_ 	$self instvar drophead_		;# idea stolen from CBQ and Kevin	set nactive_ 0	set classifier_ [new Classifier/Hash/Fid/FQ 33]	$classifier_ set fq_ $self	#$self add-to-head $classifier_	$head_ target $classifier_	# XXX	# put the ttl checker after the delay	# so we don't have to worry about accounting	# for ttl-drops within the trace and/or monitor	# fabric	#	$queue_ set secsPerByte_ [expr 8.0 / [$link_ set bandwidth_]]}FQLink instproc new-flow { src dst fid } {	$self instvar classifier_ nactive_ queue_ link_ drpT_	incr nactive_	set type [$class set queueManagement_]	set q [new Queue/$type]	#XXX yuck	if { $type == "RED" } {	 	set bw [$link_ set bandwidth_]		$q set ptc_ [expr $bw / (8. * [$q set mean_pktsize_])]	}	$q drop-target $drpT_	set slot [$classifier_ installNext $q]	$classifier_ set-hash auto $src $dst $fid $slot	$q target $queue_	$queue_ install $fid $q}#XXX ask Kannan why this isn't in otcl base class.FQLink instproc up? { } {	return up}# ## #Added by ratul for RedPDQueue# ## Queue/RED/PD instproc makeflowmon { link {cltype "SrcDestFid"} {cslots 29}} {#     set flowmon [new QueueMonitor/ED/Flowmon]#     set cl [new Classifier/Hash/$cltype $cslots]    #     $cl proc unknown-flow { src dst fid } {# 	set nflow [new QueueMonitor/ED/Flow/RedPD]# 	set slot [$self installNext $nflow]# 	#     	puts "New Flow : $nflow at slot $slot"# 	$self set-hash auto $src $dst $fid $slot# 	#     	puts "Installed It\n";#     }    #     $cl proc no-slot slotnum {# 	puts stderr "classifier $self, no-slot for slotnum $slotnum"#     }    #     $flowmon classifier $cl#     $self attach-flowmon $flowmon    #     set isnoop [new SnoopQueue/In]#     set osnoop [new SnoopQueue/Out]#     set dsnoop [new SnoopQueue/Drop]#     set edsnoop [new SnoopQueue/EDrop]    #     $link attach-monitors $isnoop $osnoop $dsnoop $flowmon#     $edsnoop set-monitor $flowmon#     $self early-drop-target $edsnoop #     set ns [Simulator instance]#     $edsnoop target [$ns set nullAgent_]	#     # $edsnoop target [$dsnoop target]#     # $edsnoop drop-target [$dsnoop drop-target] #     $self drop-target $dsnoop    #     return $flowmon# }	############################################################## Stuff below has been added to enable queue specific tracing##Blame me if anything is broken below - ratul############################################################ attach-nam-traces: Only conventional trace objects are understood by nam currently. # do not attach fancy trace objects here. nam will crash in this case.#Queue instproc attach-nam-traces {src dst file} {    	#valid only if the default trace type in attach-traces is Drop, Enque, Deque.	#see comment above.	#this function should be different for different queue when needed.		$self attach-traces $src $dst $file "nam"}## Dummy function for all the queues that don't implement attach-traces#Queue instproc attach-traces {src dst file {op ""}} {	#Do nothing here}## Added to be able to trace the edrop events #Queue/RED instproc attach-traces {src dst file {op ""}} {	        set ns [Simulator instance]	set type [$self trace-type]		#nam does not understand anything else yet. 	if {$op == "nam"} {		set type "Drop"	}		set newtrace [$ns create-trace $type $file $src $dst $op]		#    puts "In attach-trace"	set oldTrace [$self edrop-trace]	#    puts "oldTrace - $oldTrace"	if {$oldTrace!=0} {		#	puts "exists"		$newtrace target $oldTrace	} else {		#	puts "Does not exist"		$newtrace target [$ns set nullAgent_]	}		$self edrop-trace $newtrace}# ## # Added to be able to trace the mon_edrop and edrop events# ## Queue/RED/PD instproc attach-traces {src dst file {op ""}} {#     $self next $src $dst $file $op#     set ns [Simulator instance]#     set type [$self mon-trace-type]    #     #nam does not understand anything else yet#     if {$op == "nam"} {# 	set type "Drop"#     }#     set medtrace [$ns create-trace $type $file $src $dst $op]    #     set oldTrace [$self mon-edrop-trace]#     if {$oldTrace!=0} {# 	puts "exists"# 	$medtrace target $oldTrace#     } else {# 	puts "Does not exist"# 	$medtrace target [$ns set nullAgent_]#     }#     $self mon-edrop-trace $medtrace# }

⌨️ 快捷键说明

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