📄 dynamics.tcl
字号:
## Copyright (c) 1997 by the University of Southern California# All rights reserved.## Permission to use, copy, modify, and distribute this software and its# documentation in source and binary forms for non-commercial purposes# and without fee is hereby granted, provided that the above copyright# notice appear in all copies and that both the copyright notice and# this permission notice appear in supporting documentation. and that# any documentation, advertising materials, and other materials related# to such distribution and use acknowledge that the software was# developed by the University of Southern California, Information# Sciences Institute. The name of the University may not be used to# endorse or promote products derived from this software without# specific prior written permission.## THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about# the suitability of this software for any purpose. THIS SOFTWARE IS# PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,# INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.## Other copyrights might apply to parts of this software and are so# noted when applicable.### Maintainer: <kannan@isi.edu>.## The API for this code is still somewhat fluid and subject to change.# Check the documentation for details.Class rtQueueSimulator instproc rtmodel { dist parms args } { set ret "" if { [rtModel info subclass rtModel/$dist] != "" } { $self instvar rtModel_ set ret [eval new rtModel/$dist $self] eval $ret set-elements $args eval $ret set-parms $parms set trace [$self get-ns-traceall] if {$trace != ""} { $ret trace $self $trace } set trace [$self get-nam-traceall] if {$trace != ""} { $ret trace $self $trace "nam" } if [info exists rtModel_] { lappend rtModel_ $ret } else { set rtModel_ $ret } } return $ret}Simulator instproc rtmodel-configure {} { $self instvar rtq_ rtModel_ if [info exists rtModel_] { set rtq_ [new rtQueue $self] foreach m $rtModel_ { $m configure } }}Simulator instproc rtmodel-at {at op args} { set parms [list $op $at] eval $self rtmodel Manual [list $parms] $args}Simulator instproc rtmodel-delete model { $self instvar rtModel_ set idx [lsearch -exact $rtModel_ $model] if { $idx != -1 } { delete $model set rtModel_ [lreplace $rtModel_ $idx $idx] }}#rtQueue instproc init ns { $self next $self instvar ns_ set ns_ $ns}rtQueue instproc insq-i { interval obj iproc args } { $self instvar rtq_ ns_ set time [expr $interval + [$ns_ now]] if ![info exists rtq_($time)] { $ns_ at $time "$self runq $time" } lappend rtq_($time) "$obj $iproc $args" return $time}rtQueue instproc insq { at obj iproc args } { $self instvar rtq_ ns_ if {[$ns_ now] >= $at} { puts stderr "$proc: Cannot set event in the past" set at "" } else { if ![info exists rtq_($at)] { $ns_ at $at "$self runq $at" } lappend rtq_($at) "$obj $iproc $args" } return $at}rtQueue instproc delq { time obj } { $self instvar rtq_ set ret "" set nevent "" if [info exists rtq_($time)] { foreach event $rtq_($time) { if {[lindex $event 0] != $obj} { lappend nevent $event } else { set ret $event } } set rtq_($time) $nevent ;# XXX } return ret}rtQueue instproc runq { time } { $self instvar rtq_ set objects "" foreach event $rtq_($time) { set obj [lindex $event 0] set iproc [lindex $event 1] set args [lrange $event 2 end] eval $obj $iproc $args lappend objects $obj } foreach obj $objects { $obj notify } unset rtq_($time)}#Class rtModelrtModel set rtq_ ""rtModel instproc init ns { $self next $self instvar ns_ startTime_ finishTime_ set ns_ $ns set startTime_ [$class set startTime_] set finishTime_ [$class set finishTime_]}rtModel instproc set-elements args { $self instvar ns_ links_ nodes_ if { [llength $args] == 2 } { set n0 [lindex $args 0] set n1 [lindex $args 1] set n0id [$n0 id] set n1id [$n1 id] set nodes_($n0id) $n0 set nodes_($n1id) $n1 set links_($n0id:$n1id) [$ns_ link $n0 $n1] set links_($n1id:$n0id) [$ns_ link $n1 $n0] } else { set n0 [lindex $args 0] set n0id [$n0 id] set nodes_($n0id) $n0 foreach nbr [$n0 set neighbor_] { set n1 $nbr set n1id [$n1 id] set nodes_($n1id) $n1 set links_($n0id:$n1id) [$ns_ link $n0 $n1] set links_($n1id:$n0id) [$ns_ link $n1 $n0] } }}rtModel instproc set-parms args { $self instvar startTime_ upInterval_ downInterval_ finishTime_ set cls [$self info class] foreach i {startTime_ upInterval_ downInterval_ finishTime_} { if [catch "$cls set $i" $i] { set $i [$class set $i] } } set off "-" set up "-" set dn "-" set fin "-" switch [llength $args] { 4 { set off [lindex $args 0] set up [lindex $args 1] set dn [lindex $args 2] set fin [lindes $args 3] } 3 { set off [lindex $args 0] set up [lindex $args 1] set dn [lindex $args 2] } 2 { set up [lindex $args 0] set dn [lindex $args 1] } } if {$off != "-" && $off != ""} { set startTime_ $off } if {$up != "-" && $up != ""} { set upInterval_ $up } if {$dn != "-" && $dn != ""} { set downInterval_ $dn } if {$fin != "-" && $fin != ""} { set finishTime_ $fin }}rtModel instproc configure {} { $self instvar ns_ links_ if { [rtModel set rtq_] == "" } { rtModel set rtq_ [$ns_ set rtq_] } foreach l [array names links_] { $links_($l) dynamic } $self set-first-event}rtModel instproc set-event-exact {fireTime op} { $self instvar ns_ finishTime_ if {$finishTime_ != "-" && $fireTime > $finishTime_} { if {$op == up} { [rtModel set rtq_] insq $finishTime_ $self $op } } else { [rtModel set rtq_] insq $fireTime $self $op }}rtModel instproc set-event {interval op} { $self instvar ns_ $self set-event-exact [expr [$ns_ now] + $interval] $op}rtModel instproc set-first-event {} { $self instvar startTime_ upInterval_ $self set-event [expr $startTime_ + $upInterval_] down}rtModel instproc up {} { $self instvar links_ foreach l [array names links_] { $links_($l) up }}rtModel instproc down {} { $self instvar links_ foreach l [array names links_] { $links_($l) down }}rtModel instproc notify {} { $self instvar nodes_ ns_ foreach n [array names nodes_] { $nodes_($n) intf-changed } [$ns_ get-routelogic] notify}rtModel instproc trace { ns f {op ""} } { $self instvar links_ foreach l [array names links_] { $links_($l) trace-dynamics $ns $f $op }}## Exponential link failure/recovery models#Class rtModel/Exponential -superclass rtModelrtModel/Exponential instproc set-first-event {} { $self instvar startTime_ upInterval_ $self set-event [expr $startTime_ + [exponential] * $upInterval_] down}rtModel/Exponential instproc up { } { $self next $self instvar upInterval_ $self set-event [expr [exponential] * $upInterval_] down}rtModel/Exponential instproc down { } { $self next $self instvar downInterval_ $self set-event [expr [exponential] * $downInterval_] up}## Deterministic link failure/recovery models#Class rtModel/Deterministic -superclass rtModelrtModel/Deterministic instproc up { } { $self next $self instvar upInterval_ $self set-event $upInterval_ down}rtModel/Deterministic instproc down { } { $self next $self instvar downInterval_ $self set-event $downInterval_ up}## Route Dynamics instantiated through a trace file.# Invoked through:## $ns_ rtmodel Trace $traceFile $node1 [$node2 ... ]#Class rtModel/Trace -superclass rtModelrtModel/Trace instproc get-next-event {} { $self instvar tracef_ links_ while {[gets $tracef_ event] >= 0} { set toks [split $event] if [info exists links_([lindex $toks 3]:[lindex $toks 4])] { return $toks } } return ""}rtModel/Trace instproc set-trace-events {} { $self instvar ns_ nextEvent_ evq_ set time [lindex $nextEvent_ 1] while {$nextEvent_ != ""} { set nextTime [lindex $nextEvent_ 1] if {$nextTime < $time} { puts stderr "event $nextEvent_ is before current time $time. ignored." continue } if {$nextTime > $time} break if ![info exists evq_($time)] { set op [string range [lindex $nextEvent_ 2] 5 end] $self set-event-exact $time $op set evq_($time) 1 } set nextEvent_ [$self get-next-event] }}rtModel/Trace instproc set-parms traceFile { $self instvar tracef_ nextEvent_ if [catch "open $traceFile r" tracef_] { puts stderr "cannot open $traceFile" } else { set nextEvent_ [$self get-next-event] if {$nextEvent_ == ""} { puts stderr "no relevant events in $traceFile" } }}rtModel/Trace instproc set-first-event {} { $self set-trace-events}rtModel/Trace instproc up {} { $self next $self set-trace-events}rtModel/Trace instproc down {} { $self next $self set-trace-events}## One-shot route dynamics events# Invoked through:## $ns_ link-op $op $at $node1 [$node2 ...]# or# $ns_ rtmodel Manual {$op $at} $node1 [$node2 ...]#Class rtModel/Manual -superclass rtModelrtModel/Manual instproc set-first-event {} { $self instvar op_ at_ $self set-event-exact $at_ $op_ ;# you could concievably set a finishTime_?}rtModel/Manual instproc set-parms {op at} { $self instvar op_ at_ set op_ $op set at_ $at}rtModel/Manual instproc notify {} { $self next delete $self ;# XXX wierd code alert. # If needed, this could be commented out, on the assumption that # manual settings will be very limited, and hence not a sufficient # drag on memory resources. For now, play it safe (or is it risky?)}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -