📄 ns-lib.tcl
字号:
## Copyright (c) 1996 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: /home/mole/u0/bkarp/cvsroot/ns-2.1b6/tcl/lib/ns-lib.tcl,v 1.1.1.1 1999/07/29 03:27:35 bkarp Exp $### Word of warning to developers:# this code (and all it sources) is compiled into the# ns executable. You need to rebuild ns or explicitly# source this code to see changes take effect.#proc warn {msg} { global warned_ if {![info exists warned_($msg)]} { puts stderr "warning: $msg" set warned_($msg) 1 }}if {[info commands debug] == ""} { proc debug args { warn {Script debugging disabled. Reconfigure with --with-tcldebug, and recompile.} }}proc assert args { if [catch "expr $args" ret] { set ret [eval $args] } if {! $ret} { error "assertion failed: $args" }}proc find-max list { set max 0 foreach val $list { if {$val > $max} { set max $val } } return $max}## Create the core OTcl class called "Simulator".# This is the principal interface to the simulation engine.#Class Simulatorsource ns-autoconf.tclsource ns-address.tclsource ns-node.tclsource ns-hiernode.tclsource ns-mobilenode.tclsource ns-bsnode.tclsource ns-link.tclsource ns-source.tclsource ns-compat.tclsource ns-nam.tclsource ns-packet.tclsource ns-queue.tclsource ns-trace.tclsource ns-random.tclsource ns-agent.tclsource ns-route.tclsource ns-errmodel.tclsource ns-intserv.tclsource ns-cmutrace.tclsource ns-mip.tcl#source ns-wireless-mip.tclsource ../rtp/session-rtp.tclsource ../interface/ns-iface.tclsource ../lan/ns-mac.tclsource ../lan/ns-ll.tclsource ../lan/vlan.tclsource ../mcast/timer.tclsource ../mcast/ns-mcast.tclsource ../mcast/McastProto.tclsource ../mcast/DM.tclsource ../ctr-mcast/CtrMcast.tclsource ../ctr-mcast/CtrMcastComp.tclsource ../ctr-mcast/CtrRPComp.tclsource ../mcast/srm.tclsource ../mcast/srm-ssm.tclsource ../mcast/mftp_snd.tclsource ../mcast/mftp_rcv.tclsource ../mcast/mftp_rcv_stat.tclsource ../mcast/McastMonitor.tclsource ../rlm/rlm.tclsource ../rlm/rlm-ns.tclsource ../session/session.tclsource ../webcache/http-server.tclsource ../webcache/http-cache.tclsource ../webcache/http-agent.tclsource ../webcache/http-mcache.tclsource ns-namsupp.tclsource ../mobility/dsdv.tclsource ../mobility/dsr.tclsource ../mobility/gpsr.tclsource ../mobility/com.tclsource ns-default.tclsource ../emulate/ns-emulate.tclSimulator instproc init args { $self create_packetformat #the calendar scheduler doesn't work on big mobile network runs #it dies around 240 secs... #$self use-scheduler List $self use-scheduler Calendar $self set nullAgent_ [new Agent/Null] $self set-address-format def eval $self next $args}Simulator instproc nullagent {} { $self instvar nullAgent_ return $nullAgent_}Simulator instproc use-scheduler type { $self instvar scheduler_ if [info exists scheduler_] { if { [$scheduler_ info class] == "Scheduler/$type" } { return } else { delete $scheduler_ } } set scheduler_ [new Scheduler/$type] $scheduler_ now}## A simple method to wrap any object around# a trace object that dumps to stdout#Simulator instproc dumper obj { set t [$self alloc-trace hop stdout] $t target $obj return $t}# Default behavior is changed: consider nam as not initialized if # no shape OR color parameter is givenSimulator instproc node args { $self instvar Node_ if { [Simulator info vars EnableMcast_] != "" } { warn "Flag variable Simulator::EnableMcast_ discontinued.\n\t\ Use multicast methods as:\n\t\t\ % set ns \[new Simulator -multicast on]\n\t\t\ % \$ns multicast" $self multicast Simulator unset EnableMcast_ } if { [Simulator info vars NumberInterfaces_] != "" } { warn "Flag variable Simulator::NumberInterfaces_ discontinued.\n\t\ Setting (or not) this variable will not affect the simulations." Simulator unset NumberInterfaces_ } set node [new [Simulator set node_factory_] $args] set Node_([$node id]) $node $node set ns_ $self if [$self multicast?] { $node enable-mcast $self } $self check-node-num return $node}Simulator instproc hier-node haddr { error "now create hier-nodes with just [$ns_ node $haddr]"}Simulator instproc now {} { $self instvar scheduler_ return [$scheduler_ now]}Simulator instproc at args { $self instvar scheduler_ return [eval $scheduler_ at $args]}Simulator instproc at-now args { $self instvar scheduler_ return [eval $scheduler_ at-now $args]}Simulator instproc cancel args { $self instvar scheduler_ return [eval $scheduler_ cancel $args]}Simulator instproc after {ival args} { eval $self at [expr [$self now] + $ival] $args}## check if total num of nodes exceed 2 to the power n # where <n=node field size in address>#Simulator instproc check-node-num {} { AddrParams instvar nodebits_ if {[Node set nn_] > [expr pow(2, $nodebits_)]} { error "Number of nodes exceeds node-field-size of $nodebits_ bits" } if [Simulator set EnableHierRt_] { $self chk-hier-field-lengths }}## Check if number of items at each hier level (num of nodes, or clusters or domains)# exceed size of that hier level field size (in bits). should be modified to support # n-level of hierarchies#Simulator instproc chk-hier-field-lengths {} { AddrParams instvar domain_num_ cluster_num_ nodes_num_ NodeMask_ if [info exists domain_num_] { if {[expr $domain_num_ - 1]> $NodeMask_(1)} { error "\# of domains exceed dom-field-size " } } if [info exists cluster_num_] { set maxval [expr [find-max $cluster_num_] - 1] if {$maxval > [expr pow(2, $NodeMask_(2))]} { error "\# of clusters exceed clus-field-size " } } if [info exists nodes_num_] { set maxval [expr [find-max $nodes_num_] -1] if {$maxval > [expr pow(2, $NodeMask_(3))]} { error "\# of nodess exceed node-field-size" } }}Simulator instproc run {} { #$self compute-routes $self check-node-num $self rtmodel-configure ;# in case there are any [$self get-routelogic] configure $self instvar scheduler_ Node_ link_ started_ set started_ 1 # # Reset every node, which resets every agent. # foreach nn [array names Node_] { $Node_($nn) reset } # # Also reset every queue # foreach qn [array names link_] { set q [$link_($qn) queue] $q reset } # Do all nam-related initialization here $self init-nam return [$scheduler_ run]}Simulator instproc halt {} { $self instvar scheduler_ $scheduler_ halt}Simulator instproc dumpq {} { $self instvar scheduler_ $scheduler_ dumpq}Simulator instproc is-started {} { $self instvar started_ return [info exists started_]}Simulator instproc clearMemTrace {} { $self instvar scheduler_ $scheduler_ clearMemTrace}Simulator instproc simplex-link { n1 n2 bw delay qtype args } { $self instvar link_ queueMap_ nullAgent_ set sid [$n1 id] set did [$n2 id] if [info exists queueMap_($qtype)] { set qtype $queueMap_($qtype) } # construct the queue set qtypeOrig $qtype switch -exact $qtype { ErrorModule { if { [llength $args] > 0 } { set q [eval new $qtype $args] } else { set q [new $qtype Fid] } } intserv { set qtype [lindex $args 0] set q [new Queue/$qtype] } default { set q [new Queue/$qtype] } } # Now create the link switch -exact $qtypeOrig { RTM { set c [lindex $args 1] set link_($sid:$did) [new CBQLink \ $n1 $n2 $bw $delay $q $c] } CBQ - CBQ/WRR { # assume we have a string of form "linktype linkarg" if {[llength $args] == 0} { # default classifier for cbq is just Fid type set c [new Classifier/Hash/Fid 33] } else { set c [lindex $args 1] } set link_($sid:$did) [new CBQLink \ $n1 $n2 $bw $delay $q $c] } FQ { set link_($sid:$did) [new FQLink $n1 $n2 $bw $delay $q] } intserv { #XX need to clean this up set link_($sid:$did) [new IntServLink \ $n1 $n2 $bw $delay $q \ [concat $qtypeOrig $args]] } default { set link_($sid:$did) [new SimpleLink \ $n1 $n2 $bw $delay $q] } } $n1 add-neighbor $n2 #XXX yuck if {[string first "RED" $qtype] != -1} { $q link [$link_($sid:$did) set link_] } set trace [$self get-ns-traceall] if {$trace != ""} { $self trace-queue $n1 $n2 $trace } set trace [$self get-nam-traceall] if {$trace != ""} { $self namtrace-queue $n1 $n2 $trace } # Register this simplex link in nam link list. Treat it as # a duplex link in nam $self register-nam-linkconfig $link_($sid:$did)}## This is used by Link::orient to register/update the order in which links # should created in nam. This is important because different creation order# may result in different layout.## A poor hack. :( Any better ideas?#Simulator instproc register-nam-linkconfig link { $self instvar linkConfigList_ link_ if [info exists linkConfigList_] { # Check whether the reverse simplex link is registered, # if so, don't register this link again. # We should have a separate object for duplex link. set i1 [[$link src] id] set i2 [[$link dst] id] if [info exists link_($i2:$i1)] { set pos [lsearch $linkConfigList_ $link_($i2:$i1)] if {$pos >= 0} { set a1 [$link_($i2:$i1) get-attribute "ORIENTATION"] set a2 [$link get-attribute "ORIENTATION"] if {$a1 == "" && $a2 != ""} { # If this duplex link has not been # assigned an orientation, do it. set linkConfigList_ \ [lreplace $linkConfigList_ $pos $pos] } else { return } } } # Remove $link from list if it's already there set pos [lsearch $linkConfigList_ $link] if {$pos >= 0} { set linkConfigList_ \ [lreplace $linkConfigList_ $pos $pos] } } lappend linkConfigList_ $link}## GT-ITM may occasionally generate duplicate links, so we need this check# to ensure duplicated links do not appear in nam trace files.#Simulator instproc remove-nam-linkconfig {i1 i2} { $self instvar linkConfigList_ link_ if ![info exists linkConfigList_] { return } set pos [lsearch $linkConfigList_ $link_($i1:$i2)] if {$pos >= 0} { set linkConfigList_ [lreplace $linkConfigList_ $pos $pos] return } set pos [lsearch $linkConfigList_ $link_($i2:$i1)] if {$pos >= 0} { set linkConfigList_ [lreplace $linkConfigList_ $pos $pos] }}Simulator instproc duplex-link { n1 n2 bw delay type args } { $self instvar link_ set i1 [$n1 id] set i2 [$n2 id] if [info exists link_($i1:$i2)] { $self remove-nam-linkconfig $i1 $i2 } eval $self simplex-link $n1 $n2 $bw $delay $type $args eval $self simplex-link $n2 $n1 $bw $delay $type $args}Simulator instproc duplex-intserv-link { n1 n2 bw pd sched signal adc args } { eval $self duplex-link $n1 $n2 $bw $pd intserv $sched $signal $adc $args}Simulator instproc simplex-link-op { n1 n2 op args } { $self instvar link_ eval $link_([$n1 id]:[$n2 id]) $op $args}Simulator instproc duplex-link-op { n1 n2 op args } { $self instvar link_ eval $link_([$n1 id]:[$n2 id]) $op $args eval $link_([$n2 id]:[$n1 id]) $op $args}Simulator instproc flush-trace {} { $self instvar alltrace_ if [info exists alltrace_] { foreach trace $alltrace_ { $trace flush } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -