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

通讯编程

开发平台:

Visual C++

  1. #
  2. # Copyright (c) 1996 Regents of the University of California.
  3. # All rights reserved.
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. # 1. Redistributions of source code must retain the above copyright
  8. #    notice, this list of conditions and the following disclaimer.
  9. # 2. Redistributions in binary form must reproduce the above copyright
  10. #    notice, this list of conditions and the following disclaimer in the
  11. #    documentation and/or other materials provided with the distribution.
  12. # 3. All advertising materials mentioning features or use of this software
  13. #    must display the following acknowledgement:
  14. #  This product includes software developed by the MASH Research
  15. #  Group at the University of California Berkeley.
  16. # 4. Neither the name of the University nor of the Research Group may be
  17. #    used to endorse or promote products derived from this software without
  18. #    specific prior written permission.
  19. # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. # SUCH DAMAGE.
  30. #
  31. # @(#) $Header: /cvsroot/nsnam/ns-2/tcl/rlm/rlm-thesis.tcl,v 1.1 1998/02/20 20:46:48 bajaj Exp $
  32. #
  33. #
  34. # exponential factor for backing off join-timer
  35. #
  36. set rlm_param(alpha) 4
  37. set rlm_param(alpha) 2
  38. set rlm_param(beta) 0.75
  39. set rlm_param(init-tj) 1.5
  40. set rlm_param(init-tj) 10
  41. set rlm_param(init-tj) 5
  42. set rlm_param(init-td) 5
  43. #XXX
  44. #set rlm_param(init-td) 10
  45. set rlm_param(init-td-var) 2
  46. set rlm_param(max) 600
  47. #XXX
  48. set rlm_param(max) 60
  49. set rlm_param(g1) 0.25
  50. set rlm_param(g2) 0.25
  51. #XXX
  52. #set rlm_param(target-exp-time) 5
  53. #puts stderr "rlm: scaling min-rate by M=$M"
  54. #set rlm_param(max) [expr $rlm_param(target-exp-time) * 60 * $M]
  55. #XXX
  56. #puts stderr "rlm: scaling alpha by M=$M"
  57. #set rlm_param(alpha) [expr $rlm_param(alpha) * $M]
  58. MMG instproc neq {} {
  59. $self instvar equilibrium
  60. set n 0
  61. foreach v [array names equilibrium] {
  62. if $equilibrium($v) {
  63. incr n
  64. }
  65. }
  66. return $n
  67. }
  68. MMG instproc check-equilibrium {} {
  69. global equilibrium rlm_param NLEVEL
  70. $self instvar equilibrium layer
  71. if ![info exists equilibrium] {
  72. set equilibrium 0
  73. }
  74. # see if the next higher-level is maxed out
  75. set n [expr [$self subscription] + 1]
  76. if { $n >= $NLEVEL || [$layer($n) timer] >= $rlm_param(max) } {
  77. set eq 1
  78. } else {
  79. set eq 0
  80. }
  81. if { $equilibrium != $eq } {
  82. set equilibrium $eq
  83. $self debug "EQ $eq [$self neq]"
  84. }
  85. }
  86. MMG instproc backoff-one { n alpha } {
  87. $self debug "BACKOFF $n by $alpha"
  88. $self instvar layer
  89. $layer($n) backoff $alpha
  90. }
  91. MMG instproc backoff n {
  92. $self debug "BACKOFF $n"
  93. global rlm_param
  94. $self instvar maxlevel layer
  95. set alpha $rlm_param(alpha)
  96. set L $layer($n)
  97. $L backoff $alpha
  98. incr n
  99. while { $n <= $maxlevel } {
  100. $layer($n) peg-backoff $L
  101. incr n
  102. }
  103. $self check-equilibrium
  104. }
  105. MMG instproc highest_level_pending {} {
  106. $self instvar maxlevel
  107. set m ""
  108. set n 0
  109. incr n
  110. while { $n <= $maxlevel } {
  111. if [$self level_pending $n] {
  112. set m $n
  113. }
  114. incr n
  115. }
  116. return $m
  117. }
  118. MMG instproc rlm_update_D  D {
  119. #
  120. # update detection time estimate
  121. #
  122. global rlm_param
  123. $self instvar TD TDVAR
  124. set v [expr abs($D - $TD)]
  125. set TD [expr $TD * (1 - $rlm_param(g1)) 
  126. + $rlm_param(g1) * $D]
  127. set TDVAR [expr $TDVAR * (1 - $rlm_param(g2)) 
  128.        + $rlm_param(g2) * $v]
  129. }
  130. MMG instproc exceed_loss_thresh {} {
  131. $self instvar h_npkts h_nlost
  132. set npkts [expr [$self mmg_pkts] - $h_npkts]
  133. if { $npkts >= 10 } {
  134. set nloss [expr [$self mmg_loss] - $h_nlost]
  135. #XXX 0.4
  136. $self debug "H-THRESH $nloss $npkts [expr double($nloss) / ($nloss + $npkts)]"
  137. if { [expr double($nloss) / ($nloss + $npkts)] > 0.25 } {
  138. return 1
  139. }
  140. }
  141. return 0
  142. }
  143. MMG instproc enter_M {} {
  144. $self set-state /M
  145. $self set_TD_timer_wait
  146. $self instvar h_npkts h_nlost
  147. set h_npkts [$self mmg_pkts]
  148. set h_nlost [$self mmg_loss]
  149. }
  150. MMG instproc enter_D {} {
  151. $self set-state /D
  152. $self set_TD_timer_conservative
  153. }
  154. MMG instproc enter_H {} {
  155. $self set_TD_timer_conservative
  156. $self set-state /H
  157. }
  158. MMG instproc log-loss {} {
  159. $self debug "LOSS [$self mmg_loss]"
  160. $self instvar state subscription pending_ts
  161. if { $state == "/M" } {
  162. if [$self exceed_loss_thresh] {
  163. cancel_timer TD $self
  164. $self drop-layer
  165. $self check-equilibrium
  166. $self enter_D
  167. }
  168. return
  169. }
  170. if { $state == "/S" } {
  171. cancel_timer TD $self
  172. set n [$self highest_level_pending]
  173. if { $n != "" } {
  174. #
  175. # there is a join-experiment in progress --
  176. # back off the join-experiment rate for the
  177. # layer that was doing the experiment
  178. # if we're at that layer, drop it, and
  179. # update the detection time estimator.
  180. #
  181. $self backoff $n
  182. if { $n == $subscription } {
  183. set ts $pending_ts($subscription)
  184. $self rlm_update_D [expr [ns-now] - $ts]
  185. $self drop-layer
  186. $self check-equilibrium
  187. $self enter_D
  188. return
  189. }
  190. #
  191. # If we're at the level just below the experimental
  192. # layer that cause a problem, reset our join timer.
  193. # The logic is that we just effectively ran an
  194. # experiment, so we might as well reset our timer.
  195. # This improves the scalability of the algorithm
  196. # by limiting the frequency of experiments.
  197. #
  198. if { $n == [expr $subscription + 1] } {
  199. cancel_timer TJ $self
  200. $self set_TJ_timer
  201. }
  202. }
  203. if [$self our_level_recently_added] {
  204. $self enter_M
  205. return
  206. }
  207. $self enter_H
  208. return
  209. }
  210. if { $state == "/H" || $state == "/D" } {
  211. return
  212. }
  213. puts stderr "rlm state machine botched"
  214. exit -1
  215. }
  216. MMG instproc relax_TJ {} {
  217. $self instvar subscription layer
  218. if { $subscription > 0 } {
  219. $layer($subscription) relax
  220. $self check-equilibrium
  221. }
  222. }
  223. MMG instproc trigger_TD {} {
  224. $self instvar state
  225. if { $state == "/H" } {
  226. $self enter_M
  227. return
  228. }
  229. if { $state == "/D" || $state == "/M" } {
  230. $self set-state /S
  231. $self set_TD_timer_conservative
  232. return
  233. }
  234. if { $state == "/S" } {
  235. $self relax_TJ
  236. $self set_TD_timer_conservative
  237. return
  238. }
  239. puts stderr "trigger_TD: rlm state machine botched $state)"
  240. exit -1
  241. }
  242. MMG instproc set_TJ_timer {} {
  243. global rlm_param
  244. $self instvar subscription layer
  245. set n [expr $subscription + 1]
  246. if ![info exists layer($n)] {
  247. #
  248. # no timer -- means we're maximally subscribed
  249. #
  250. return
  251. }
  252. set I [$layer($n) timer]
  253. set d [expr $I / 2.0 + [trunc_exponential $I]]
  254. $self debug "TJ $d"
  255. set_timer TJ $self $d
  256. }
  257. MMG instproc set_TD_timer_conservative {} {
  258. $self instvar TD TDVAR
  259. set delay [expr $TD + 1.5 * $TDVAR]
  260. set_timer TD $self $delay
  261. }
  262. MMG instproc set_TD_timer_wait {} {
  263. $self instvar TD TDVAR
  264. #XXX factor of 2?
  265. $self instvar subscription
  266. set k [expr $subscription / 2. + 1.5]
  267. # set k 2
  268. set_timer TD $self [expr $TD + $k * $TDVAR]
  269. }
  270. #
  271. # Return true iff the time given by $ts is recent enough
  272. # such that any action taken since then is likely to influence the
  273. # present or future
  274. #
  275. MMG instproc is-recent { ts } {
  276. $self instvar TD TDVAR
  277. set ts [expr $ts + ($TD + 2 * $TDVAR)]
  278. if { $ts > [ns-now] } {
  279. return 1
  280. }
  281. return 0
  282. }
  283. MMG instproc level_pending n {
  284. $self instvar pending_ts
  285. if { [info exists pending_ts($n)] && 
  286.  [$self is-recent $pending_ts($n)] } {
  287. return 1
  288. }
  289. return 0
  290. }
  291. MMG instproc level_recently_joined n {
  292. $self instvar join_ts
  293. if { [info exists join_ts($n)] && 
  294.  [$self is-recent $join_ts($n)] } {
  295. return 1
  296. }
  297. return 0
  298. }
  299. MMG instproc pending_inferior_jexps {} {
  300. set n 0
  301. $self instvar subscription
  302. while { $n <= $subscription } { 
  303. if [$self level_recently_joined $n] {
  304. return 1
  305. }
  306. incr n
  307. }
  308. $self debug "NO-PEND-INF"
  309. return 0
  310. }
  311. #
  312. # join the next higher layer when in /S
  313. #
  314. #MINE : changed this so that at least the base layer is always subscribed to
  315. MMG instproc trigger_TJ {} {
  316. $self debug "trigger-TJ"
  317. $self instvar state ctrl subscription
  318. if { ($state == "/S" && ![$self pending_inferior_jexps] && 
  319.   [$self current_layer_getting_packets])  } {
  320. $self add-layer
  321. $self check-equilibrium
  322. set msg "add $subscription"
  323. $ctrl send $msg
  324. #XXX loop back message
  325. $self local-join
  326. }
  327. $self set_TJ_timer
  328. }
  329. MMG instproc our_level_recently_added {} {
  330. $self instvar subscription layer
  331. return [$self is-recent [$layer($subscription) last-add]]
  332. }
  333. proc recv_ctrl { mmg msg } {
  334. $mmg recv-ctrl $msg
  335. }
  336. MMG instproc recv-ctrl msg {
  337. $self instvar join_ts pending_ts subscription
  338. $self debug "X-JOIN $msg"
  339. set what [lindex $msg 0]
  340. if { $what != "add" } {
  341. #puts RECV/$msg
  342. return
  343. }
  344. set level [lindex $msg 1]
  345. #
  346. #XXX
  347. # only set the join-ts if the outside J.E. is greater
  348. # than our level.  if not, then we do not want to falsely
  349. # increase the ts of our levels.XXX say this better.
  350. #
  351. set join_ts($level) [ns-now]
  352. if { $level > $subscription } {
  353. set pending_ts($level) [ns-now]
  354. }
  355. }
  356. MMG instproc local-join {} {
  357. $self instvar subscription pending_ts join_ts
  358. set join_ts($subscription) [ns-now]
  359. set pending_ts($subscription) [ns-now]
  360. }