dynamics.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:11k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. #  Copyright (c) 1997 by the University of Southern California
  3. #  All rights reserved.
  4. #
  5. #  This program is free software; you can redistribute it and/or
  6. #  modify it under the terms of the GNU General Public License,
  7. #  version 2, as published by the Free Software Foundation.
  8. #
  9. #  This program is distributed in the hope that it will be useful,
  10. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #  GNU General Public License for more details.
  13. #
  14. #  You should have received a copy of the GNU General Public License along
  15. #  with this program; if not, write to the Free Software Foundation, Inc.,
  16. #  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  17. #
  18. #  The copyright of this module includes the following
  19. #  linking-with-specific-other-licenses addition:
  20. #
  21. #  In addition, as a special exception, the copyright holders of
  22. #  this module give you permission to combine (via static or
  23. #  dynamic linking) this module with free software programs or
  24. #  libraries that are released under the GNU LGPL and with code
  25. #  included in the standard release of ns-2 under the Apache 2.0
  26. #  license or under otherwise-compatible licenses with advertising
  27. #  requirements (or modified versions of such code, with unchanged
  28. #  license).  You may copy and distribute such a system following the
  29. #  terms of the GNU GPL for this module and the licenses of the
  30. #  other code concerned, provided that you include the source code of
  31. #  that other code when and as the GNU GPL requires distribution of
  32. #  source code.
  33. #
  34. #  Note that people who make modified versions of this module
  35. #  are not obligated to grant this special exception for their
  36. #  modified versions; it is their choice whether to do so.  The GNU
  37. #  General Public License gives permission to release a modified
  38. #  version without this exception; this exception also makes it
  39. #  possible to release a modified version which carries forward this
  40. #  exception.
  41. #
  42. # Maintainer: <kannan@isi.edu>.
  43. #
  44. # The API for this code is still somewhat fluid and subject to change.
  45. # Check the documentation for details.
  46. Class rtQueue
  47. Simulator instproc rtmodel { dist parms args } {
  48. set ret ""
  49. if { [rtModel info subclass rtModel/$dist] != "" } {
  50. $self instvar  rtModel_
  51. set ret [eval new rtModel/$dist $self]
  52. eval $ret set-elements $args
  53. eval $ret set-parms $parms
  54. set trace [$self get-ns-traceall]
  55. if {$trace != ""} {
  56. $ret trace $self $trace
  57. }
  58. set trace [$self get-nam-traceall]
  59. if {$trace != ""} {
  60. $ret trace $self $trace "nam"
  61. }
  62. if [info exists rtModel_] {
  63. lappend rtModel_ $ret
  64. } else {
  65. set rtModel_ $ret
  66. }
  67. }
  68. return $ret
  69. }
  70. Simulator instproc rtmodel-configure {} {
  71.     $self instvar rtq_ rtModel_
  72.     if [info exists rtModel_] {
  73. set rtq_ [new rtQueue $self]
  74. foreach m $rtModel_ {
  75.     $m configure
  76. }
  77.     }
  78. }
  79. Simulator instproc rtmodel-at {at op args} {
  80.     set parms [list $op $at]
  81.     eval $self rtmodel Manual [list $parms] $args
  82. }
  83. Simulator instproc rtmodel-delete model {
  84.     $self instvar rtModel_
  85.     set idx [lsearch -exact $rtModel_ $model]
  86.     if { $idx != -1 } {
  87. delete $model
  88. set rtModel_ [lreplace $rtModel_ $idx $idx]
  89.     }
  90. }
  91. #
  92. rtQueue instproc init ns {
  93.     $self next
  94.     $self instvar ns_
  95.     set ns_ $ns
  96. }
  97. rtQueue instproc insq-i { interval obj iproc args } {
  98.     $self instvar rtq_ ns_
  99.     set time [expr $interval + [$ns_ now]]
  100.     if ![info exists rtq_($time)] {
  101. $ns_ at $time "$self runq $time"
  102.     }
  103.     lappend rtq_($time) "$obj $iproc $args"
  104.     return $time
  105. }
  106. rtQueue instproc insq { at obj iproc args } {
  107.     $self instvar rtq_ ns_
  108.     if {[$ns_ now] >= $at} {
  109. puts stderr "$proc: Cannot set event in the past"
  110. set at ""
  111.     } else {
  112. if ![info exists rtq_($at)] {
  113.     $ns_ at $at "$self runq $at"
  114. }
  115. lappend rtq_($at) "$obj $iproc $args"
  116.     }
  117.     return $at
  118. }
  119. rtQueue instproc delq { time obj } {
  120.     $self instvar rtq_
  121.     set ret ""
  122.     set nevent ""
  123.     if [info exists rtq_($time)] {
  124. foreach event $rtq_($time) {
  125.     if {[lindex $event 0] != $obj} {
  126. lappend nevent $event
  127.     } else {
  128. set ret $event
  129.     }
  130. }
  131. set rtq_($time) $nevent ;# XXX
  132.     }
  133.     return ret
  134. }
  135. rtQueue instproc runq { time } {
  136.     $self instvar rtq_
  137.     set objects ""
  138.     foreach event $rtq_($time) {
  139. set obj   [lindex $event 0]
  140. set iproc [lindex $event 1]
  141. set args  [lrange $event 2 end]
  142. eval $obj $iproc $args
  143. lappend objects $obj
  144.     }
  145.     foreach obj $objects {
  146. $obj notify
  147.     }
  148.     unset rtq_($time)
  149. }
  150. #
  151. Class rtModel
  152. rtModel set rtq_ ""
  153. rtModel instproc init ns {
  154.     $self next
  155.     $self instvar ns_ startTime_ finishTime_
  156.     set ns_ $ns
  157.     set startTime_ [$class set startTime_]
  158.     set finishTime_ [$class set finishTime_]
  159. }
  160. rtModel instproc set-elements args {
  161.     $self instvar ns_ links_ nodes_
  162.     if { [llength $args] == 2 } {
  163. set n0 [lindex $args 0]
  164. set n1 [lindex $args 1]
  165. set n0id [$n0 id]
  166. set n1id [$n1 id]
  167. set nodes_($n0id) $n0
  168. set nodes_($n1id) $n1
  169. set links_($n0id:$n1id) [$ns_ link $n0 $n1]
  170. set links_($n1id:$n0id) [$ns_ link $n1 $n0]
  171.     } else {
  172. set n0 [lindex $args 0]
  173. set n0id [$n0 id]
  174. set nodes_($n0id) $n0
  175. foreach nbr [$n0 set neighbor_] {
  176.     set n1 $nbr
  177.     set n1id [$n1 id]
  178.     
  179.     set nodes_($n1id) $n1
  180.     set links_($n0id:$n1id) [$ns_ link $n0 $n1]
  181.     set links_($n1id:$n0id) [$ns_ link $n1 $n0]
  182. }
  183.     }
  184. }
  185. rtModel instproc set-parms args {
  186.     $self instvar startTime_ upInterval_ downInterval_ finishTime_
  187.     set cls [$self info class]
  188.     foreach i {startTime_ upInterval_ downInterval_ finishTime_} {
  189. if [catch "$cls set $i" $i] {
  190.     set $i [$class set $i]
  191. }
  192.     }
  193.     set off "-"
  194.     set up  "-"
  195.     set dn  "-"
  196.     set fin "-"
  197.     switch [llength $args] {
  198. 4 {
  199.     set off [lindex $args 0]
  200.     set up  [lindex $args 1]
  201.     set dn  [lindex $args 2]
  202.     set fin [lindex $args 3]
  203. }
  204. 3 {
  205.     set off [lindex $args 0]
  206.     set up  [lindex $args 1]
  207.     set dn  [lindex $args 2]
  208. }
  209. 2 {
  210.     set up [lindex $args 0]
  211.     set dn [lindex $args 1]
  212. }
  213.     }
  214.     if {$off != "-" && $off != ""} {
  215. set startTime_ $off
  216.     }
  217.     if {$up != "-" && $up != ""} {
  218. set upInterval_ $up
  219.     }
  220.     if {$dn != "-" && $dn != ""} {
  221. set downInterval_ $dn
  222.     }
  223.     if {$fin != "-" && $fin != ""} {
  224. set finishTime_ $fin
  225.     }
  226. }
  227. rtModel instproc configure {} {
  228.     $self instvar ns_ links_
  229.     if { [rtModel set rtq_] == "" } {
  230. rtModel set rtq_ [$ns_ set rtq_]
  231.     }
  232.     foreach l [array names links_] {
  233. $links_($l) dynamic
  234.     }
  235.     $self set-first-event
  236. }
  237. rtModel instproc set-event-exact {fireTime op} {
  238.     $self instvar ns_ finishTime_
  239.     if {$finishTime_ != "-" && $fireTime > $finishTime_} {
  240. if {$op == "up"} {
  241.     [rtModel set rtq_] insq $finishTime_ $self $op
  242. }
  243.     } else {
  244. [rtModel set rtq_] insq $fireTime $self $op
  245.     }
  246. }
  247. rtModel instproc set-event {interval op} {
  248.     $self instvar ns_
  249.     $self set-event-exact [expr [$ns_ now] + $interval] $op
  250. }
  251. rtModel instproc set-first-event {} {
  252.     $self instvar startTime_ upInterval_
  253.     $self set-event [expr $startTime_ + $upInterval_] down
  254. }
  255. rtModel instproc up {} {
  256.     $self instvar links_
  257.     foreach l [array names links_] {
  258. $links_($l) up
  259.     }
  260. }
  261. rtModel instproc down {} {
  262.     $self instvar links_
  263.     foreach l [array names links_] {
  264. $links_($l) down
  265.     }
  266. }
  267. rtModel instproc notify {} {
  268.     $self instvar nodes_ ns_
  269.     foreach n [array names nodes_] {
  270. $nodes_($n) intf-changed
  271.     }
  272.     [$ns_ get-routelogic] notify
  273. }
  274. rtModel instproc trace { ns f {op ""} } {
  275.     $self instvar links_
  276.     foreach l [array names links_] {
  277. $links_($l) trace-dynamics $ns $f $op
  278.     }
  279. }
  280. #
  281. # Exponential link failure/recovery models
  282. #
  283. Class rtModel/Exponential -superclass rtModel
  284. rtModel/Exponential instproc set-first-event {} {
  285. global rtglibRNG
  286. $self instvar startTime_ upInterval_
  287. $self set-event [expr $startTime_ + [$rtglibRNG exponential] * $upInterval_] down
  288. }
  289. rtModel/Exponential instproc up { } {
  290. global rtglibRNG
  291. $self next
  292. $self instvar upInterval_
  293. $self set-event [expr [$rtglibRNG exponential] * $upInterval_] down
  294. }
  295. rtModel/Exponential instproc down { } {
  296. global rtglibRNG
  297. $self next
  298. $self instvar downInterval_
  299. $self set-event [expr [$rtglibRNG exponential] * $downInterval_] up
  300. }
  301. #
  302. # Deterministic link failure/recovery models
  303. #
  304. Class rtModel/Deterministic -superclass rtModel
  305. rtModel/Deterministic instproc up { } {
  306. $self next
  307. $self instvar upInterval_
  308. $self set-event $upInterval_ down
  309. }
  310. rtModel/Deterministic instproc down { } {
  311. $self next
  312. $self instvar downInterval_
  313. $self set-event $downInterval_ up
  314. }
  315. #
  316. # Route Dynamics instantiated through a trace file.
  317. # Invoked through:
  318. #
  319. #    $ns_ rtmodel Trace $traceFile $node1 [$node2 ... ]
  320. #
  321. Class rtModel/Trace -superclass rtModel
  322. rtModel/Trace instproc get-next-event {} {
  323.     $self instvar tracef_ links_
  324.     while {[gets $tracef_ event] >= 0} {
  325. set toks [split $event]
  326. if [info exists links_([lindex $toks 3]:[lindex $toks 4])] {
  327.     return $toks
  328. }
  329.     }
  330.     return ""
  331. }
  332. rtModel/Trace instproc set-trace-events {} {
  333.     $self instvar ns_ nextEvent_ evq_
  334.     
  335.     set time [lindex $nextEvent_ 1]
  336.     while {$nextEvent_ != ""} {
  337. set nextTime [lindex $nextEvent_ 1]
  338. if {$nextTime < $time} {
  339.     puts stderr "event $nextEvent_  is before current time $time. ignored."
  340.     continue
  341. }
  342. if {$nextTime > $time} break
  343. if ![info exists evq_($time)] {
  344.     set op [string range [lindex $nextEvent_ 2] 5 end]
  345.     $self set-event-exact $time $op
  346.     set evq_($time) 1
  347. }
  348. set nextEvent_ [$self get-next-event]
  349.     }
  350. }
  351. rtModel/Trace instproc set-parms traceFile {
  352.     $self instvar tracef_ nextEvent_
  353.     if [catch "open $traceFile r" tracef_] {
  354. puts stderr "cannot open $traceFile"
  355.     } else {
  356. set nextEvent_ [$self get-next-event]
  357. if {$nextEvent_ == ""} {
  358.     puts stderr "no relevant events in $traceFile"
  359. }
  360.     }
  361. }
  362. rtModel/Trace instproc set-first-event {} {
  363.     $self set-trace-events
  364. }
  365. rtModel/Trace instproc up {} {
  366.     $self next
  367.     $self set-trace-events
  368. }
  369. rtModel/Trace instproc down {} {
  370.     $self next
  371.     $self set-trace-events
  372. }
  373. #
  374. # One-shot route dynamics events
  375. # Invoked through:
  376. #
  377. # $ns_ link-op $op $at $node1 [$node2 ...]
  378. # or
  379. # $ns_ rtmodel Manual {$op $at} $node1 [$node2 ...]
  380. #
  381. Class rtModel/Manual -superclass rtModel
  382. rtModel/Manual instproc set-first-event {} {
  383.     $self instvar op_ at_
  384.     $self set-event-exact $at_ $op_ ;# you could concievably set a finishTime_?
  385. }
  386. rtModel/Manual instproc set-parms {op at} {
  387.     $self instvar op_ at_
  388.     set op_ $op
  389.     set at_ $at
  390. }
  391. rtModel/Manual instproc notify {} {
  392.     $self next
  393.     delete $self ;# XXX wierd code alert.
  394. # If needed, this could be commented out, on the assumption that
  395. # manual settings will be very limited, and hence not a sufficient
  396. # drag on memory resources.  For now, play it safe (or is it risky?)
  397. }