1 import MashRNG
2 import MashLog
3
4 #----------------------------------------------------------------------
5 # Class:
6 # MashTimer
7 # Description:
8 # This is a new, general timer class that is meant to complement the
9 # Timer class in Mash. It has a simpler interface, and you do not
10 # have to subclass MashTimer to define your own timeout. Instead,
11 # you pass in the timeout routine as an arguments to the constructor.
12 #----------------------------------------------------------------------
13 Class MashTimer
14
15 #--------------------------------------------------------------------
16 # Method:
17 # MashTimer init
18 # Arguments:
19 # type --
20 # a string describing the type of timer, either "once" or
21 # "periodic", or "random_periodic"
22 # timeout --
23 # timeout before callback is called.
24 # callback --
25 # which is the command to eval when timeout occurs.
26 #--------------------------------------------------------------------
27 MashTimer public init { type timeout callback } {
28 $self instvar timeout_ callback_ id_ type_
29
30 set valid_types { "once" "periodic" "random_periodic" }
31
32 if {[lsearch $valid_types $type] == -1} {
33 puts stderr "Invalid MashTimer type \"$type\" : valid types are : $valid_types"
34 }
35
36 set type_ $type
37 set timeout_ $timeout
38 set callback_ $callback
39 if {$type == "random_periodic" } {
40 if {$timeout < 0.5} {
41 error "ERROR: timeout for random periodic timer must be > 0.5. $timeout is given as timeout instead."
42 }
43 set timeout [expr $timeout + [MashRNG uniform -500 500]]
44 }
45 $self sched $timeout
46 }
47
48 #--------------------------------------------------------------------
49 # Method:
50 # MashTimer sched
51 # Description:
52 # Schedule the timeout to be called after time ms
53 #--------------------------------------------------------------------
54 MashTimer private sched {time} {
55 $self instvar id_
56 set time [expr int($time + 0.5)]
57 set id_ [after $time "$self timeout"]
58 }
59
60
61 #--------------------------------------------------------------------
62 # Method:
63 # MashTimer cancel
64 # Description:
65 # Cancel the timer.
66 #--------------------------------------------------------------------
67 MashTimer private cancel {} {
68 $self instvar id_
69 after cancel $id_
70 }
71
72
73 #--------------------------------------------------------------------
74 # Method:
75 # MashTimer resched
76 # Description:
77 # Cancel the current timer and reschedule a timeout after time ms.
78 #--------------------------------------------------------------------
79 MashTimer private resched {} {
80 $self instvar timeout_
81 $self cancel
82 $self sched $timeout_
83 }
84
85
86 #--------------------------------------------------------------------
87 # Method:
88 # MashTimer timeout
89 # Description:
90 # This callback is activated whenever the current timer expire.
91 #--------------------------------------------------------------------
92 MashTimer private timeout {} {
93 $self instvar timeout_ callback_ id_ type_
94 if {$type_ == "periodic"} {
95 set id_ [$self sched $timeout_]
96 } elseif {$type_ == "random_periodic"} {
97 set timeout [expr $timeout_ + [MashRNG uniform -500 500]]
98 set id_ [$self sched $timeout]
99 }
100
101 # Since the callback may delete the timer, we should eval this
102 # last
103 eval $callback_
104 }
105
106
107 #--------------------------------------------------------------------
108 # Method:
109 # MashTimer destroy
110 # Description:
111 # Cancel the timer, and self-destruct.
112 #--------------------------------------------------------------------
113 MashTimer private destroy {} {
114 $self cancel
115 $self next
116 }
117
118 Class MashTimer/Once -superclass MashTimer
119 MashTimer/Once instproc init { timeout callback } {
120 $self next "once" $timeout $callback
121 }
122
123 Class MashTimer/Periodic -superclass MashTimer
124 MashTimer/Periodic instproc init { timeout callback } {
125 $self next "periodic" $timeout $callback
126 }
127
128 Class MashTimer/RandomPeriodic -superclass MashTimer
129 MashTimer/RandomPeriodic instproc init { timeout callback } {
130 $self next "random_periodic" $timeout $callback
131 }
132
133 Class MashTimer/ConstBW -superclass MashTimer
134 MashTimer/ConstBW instproc init { timeout callback bw } {
135 $self instvar num_of_srcs_ threshold_ callback_ avg_size_ alpha_ bw_
136 set num_of_srcs_ 0
137 set avg_size_ 28
138 set alpha_ 0.125
139 set threshold_ $timeout
140 set callback_ $callback
141 set bw_ $bw
142
143 $self sched $timeout
144 }
145
146 MashTimer/ConstBW instproc num_of_srcs { args } {
147 $self instvar num_of_srcs_
148 if {$args == ""} {
149 return $num_of_srcs_
150 } else {
151 set num_of_srcs_ [lindex $args 0]
152 }
153 }
154
155 MashTimer/ConstBW instproc add_src { } {
156 $self instvar num_of_srcs_
157 incr num_of_srcs_
158 }
159
160 MashTimer/ConstBW instproc del_src { } {
161 $self instvar num_of_srcs_
162 incr num_of_srcs_ -1
163 }
164
165 MashTimer/ConstBW instproc add_sample { size } {
166 $self instvar avg_size_ alpha_
167 set avg_size_ [expr {$avg_size_ + $alpha_*($size+28-$avg_size_)}]
168 #MashLog info "MashTimer: sample: $size"
169 }
170
171 MashTimer/ConstBW instproc adapt { } {
172 $self instvar avg_size_ alpha_ bw_ num_of_srcs_ threshold_
173 set t [expr {1000*($num_of_srcs_*$avg_size_*8)/$bw_}]
174 #MashLog info "MashTimer: adapting:self=$self:ns=$num_of_srcs_:s=$avg_size_:bw=$bw_:timer=$t"
175 if {$t < $threshold_} {
176 return $threshold_
177 } else {
178 return $t
179 }
180 }
181
182 MashTimer/ConstBW private timeout {} {
183 $self instvar timeout_ callback_ id_ type_
184 set timeout_ [$self adapt]
185 set id_ [$self sched $timeout_]
186
187 eval $callback_
188 }
189
190 # vim:ts=8:sw=4:expandtab
191
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.