1 # timer.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1997-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #
31 # @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/common/timer.tcl,v 1.15 2002/02/03 04:25:43 lim Exp $
32
33
34 # This is the base Timer class.
35 # An application can schedule a timer using the <i>msched</i> method. When
36 # the timer expires, the <i>timeout</i> method is invoked. Applications
37 # must subclass this method.
38 Class Timer
39
40 # This class defines a periodic timer; a new timer is scheduled as soon
41 # as the current one expires. Use the <i>start</i> method to initiate the
42 # periodic timer, and the <i>cancel</i> method to stop it.
43 Class Timer/Periodic -superclass Timer
44
45 # This is an abstract base class for periodic adaptive timers. Before
46 # scheduling the next timeout, it invokes the <i>adapt</i> method to
47 # recompute the timeout. Applications must redefine this method in the
48 # subclass
49 Class Timer/Adaptive -superclass Timer
50
51 # This class can be used to create timers for sending out network packets
52 # while maintaining a constant bandwidth utilization
53 Class Timer/Adaptive/ConstBW -superclass Timer/Adaptive
54
55
56 #
57 Timer public init {} {
58 $self next
59 $self randomize 0
60 $self set randwt_ 1.0
61 }
62
63 #
64 Timer public destroy {} {
65 $self cancel
66 $self next
67 }
68
69 # Use this method to set/unset automatic randomization of the
70 # timer.
71 # <ul>
72 # <li><i>yesno</i> can take one of the following values: <i>yes</i>,
73 # <i>no</i>, 1, or 0. The default value is 1.
74 # <li><i>randwt</i> is the weight factor associated with the
75 # randomization component
76 Timer public randomize { {yesno 1} {randwt {}} } {
77 if { $randwt!={} } {
78 $self set randwt_ $randwt
79 }
80 if {$yesno=="yes"} {set yesno 1} elseif {$yesno=="no"} {set yesno 0}
81 $self set randomize_ $yesno
82 }
83
84
85 # FIXME backward compat
86 Timer private sched { t } {
87 $self msched $t
88 }
89
90
91 # This method schedules a timeout for <i>t</i> milliseconds. The timeout
92 # value may be randomized if the <i>randomize</i> method has been invoked
93 # on this object
94 Timer public msched { t } {
95 $self instvar id_ randomize_ randwt_
96
97 if [info exists id_] {
98 puts stderr "warning: $self ([$self info class]):\
99 overlapping timers"
100 }
101
102 if $randomize_ {
103 # Random number in U[-0.5,0.5]
104 set r [expr [random]/double(0x7fffffff)-0.5]
105 set t [expr $t+$t*$r*$randwt_]
106 }
107
108 set t [expr int($t+0.5)]
109 set id_ [after $t "$self do_timeout"]
110 }
111
112
113 # private method invoked every time a timeout occurs. This method invokes
114 # the <i>timeout</i> method which applications should redefine
115 Timer private do_timeout {} {
116 $self instvar id_
117 if ![info exists id_] {
118 puts stderr "warning: $self ($class) no timer id_"
119 } else {
120 unset id_
121 }
122 $self timeout
123 }
124
125
126 # Returns a boolean flag that indicates whether a timer has currently
127 # been scheduled
128 Timer public is_sched { } {
129 $self instvar id_
130 return [info exists id_]
131 }
132
133
134 # Cancels the currently scheduled timer. If there is no timer scheduled,
135 # this method simply NOPs
136 Timer public cancel {} {
137 $self instvar id_
138 if [info exists id_] {
139 after cancel $id_
140 unset id_
141 }
142 }
143
144
145 #
146 Timer/Periodic public init { {period 5000} } {
147 $self next
148 $self set period_ $period
149 }
150
151
152 # Use this method to start the periodic timer. The timer can be stopped
153 # using the <i>cancel</i> method. If the <i>period</i> argument is
154 # specified, the object sets its period to that value, otherwise it
155 # uses its last set value (possibly set by the init proc). You can invoke
156 # this method multiple times without invoking <i>cancel</i> in between.
157 # It will implicitly call <i>cancel</i> if required.
158 Timer/Periodic public start { {period {}} } {
159 $self instvar period_
160 if { $period!={} } { set period_ $period }
161
162 if [$self is_sched] { $self cancel }
163 $self msched $period_
164 }
165
166
167 #
168 Timer/Periodic instproc do_timeout {} {
169 $self instvar period_
170 $self next
171 if { [info commands $self]=="" } return
172 $self msched $period_
173 }
174
175
176 #
177 Timer/Adaptive public init { {interval 5000} } {
178 $self next
179 $self set interval_ $interval
180 }
181
182
183 # Use this method to start the periodic timer. The timer can be stopped
184 # using the <i>cancel</i> method. You can invoke
185 # this method multiple times without invoking <i>cancel</i> in between.
186 # It will implicitly call <i>cancel</i> if required.
187 Timer/Adaptive public start {} {
188 $self instvar interval_
189
190 if [$self is_sched] { $self cancel }
191 set interval_ [$self adapt $interval_]
192 $self msched [expr int($interval_+0.5)]
193 }
194
195
196 Timer/Adaptive public do_timeout {} {
197 $self next
198 if { [info commands $self]=="" } return
199 $self instvar interval_
200 set interval_ [$self adapt $interval_]
201 $self msched [expr int($interval_+0.5)]
202
203 }
204
205
206 # applications must subclass this class, and redefine their own
207 #<i>adapt</i> method in the subclass
208 Timer/Adaptive private adapt {interval} {
209 return $interval
210 }
211
212
213 #
214 Timer/Adaptive/ConstBW public init { bw {thresh {}} {size_gain {}} } {
215 $self instvar size_gain_ avgsize_ nsrcs_ bw_ thresh_ interval_
216
217 if { $size_gain!={} } {
218 set size_gain_ $size_gain
219 } else {
220 set size_gain_ 0.125
221 }
222
223 set avgsize_ 28
224 set nsrcs_ 0
225 set bw_ $bw
226
227 if { $thresh=={} } {
228 # 500ms default threshold
229 set thresh_ 500
230 } else {
231 set thresh_ $thresh
232 }
233 $self next $thresh_
234 }
235
236 # Call this method to set/retrieve the timer threshold
237 Timer/Adaptive/ConstBW public threshold { {thresh {}} } {
238 $self instvar thresh_
239 if {$thresh=={}} {
240 return $thresh_
241 } else {
242 set thresh_ $thresh
243 }
244 }
245
246 # Call this method to set/retrieve the timer bandwidth
247 Timer/Adaptive/ConstBW public bandwidth { {bw {}} } {
248 $self instvar bw_
249 if {$bw=={}} {
250 return $bw_
251 } else {
252 set bw_ $bw
253 }
254 }
255
256
257 # Call this method to provide a sample of the size of data that is being
258 # sent/received over the network
259 Timer/Adaptive/ConstBW public sample_size { size } {
260 $self instvar avgsize_ size_gain_
261 # FIXME Assume IPv4 header of 28 bytes.
262 set avgsize_ [expr $avgsize_ + $size_gain_ * ($size + 28 - $avgsize_)]
263 }
264
265
266 # Call this method to update the number of sources in the session
267 Timer/Adaptive/ConstBW public update_nsrcs { nsrcs } {
268 $self set nsrcs_ $nsrcs
269 }
270
271
272 # Call this method to retrieve the number of sources in the session
273 Timer/Adaptive/ConstBW public nsrcs { nsrcs } {
274 return [$self set nsrcs_]
275 }
276
277
278 # Call this method to increment the number of sources in the session
279 Timer/Adaptive/ConstBW public incr_nsrcs { {incr 1} } {
280 $self instvar nsrcs_
281 incr nsrcs_ $incr
282 }
283
284
285 # This method recomputes the new timeout interval
286 Timer/Adaptive/ConstBW private adapt {interval} {
287 $self instvar avgsize_ bw_ nsrcs_ thresh_
288
289 set t [expr 1000 * ($nsrcs_ * $avgsize_ * 8) / $bw_]
290 if { $t < $thresh_ } {
291 return $thresh_
292 } else {
293 return $t
294 }
295 }
296
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.