diff options
author | irungentoo <irungentoo@gmail.com> | 2013-08-16 13:11:09 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-08-16 13:11:09 -0400 |
commit | 88ff81d9def5efe69cbaf91aa41906177ba7dde9 (patch) | |
tree | cb9f149e438bcd1f18d8c1eb5d8be6b0a22f58a4 /core/timer.c | |
parent | c5af8f44a9d040a0bbe0442ec074d9fc8562dd32 (diff) |
Passed everything through astyle.
Diffstat (limited to 'core/timer.c')
-rw-r--r-- | core/timer.c | 99 |
1 files changed, 57 insertions, 42 deletions
diff --git a/core/timer.c b/core/timer.c index 06e25693..29190921 100644 --- a/core/timer.c +++ b/core/timer.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "timer.h" | 4 | #include "timer.h" |
5 | #include "network.h" | 5 | #include "network.h" |
6 | 6 | ||
7 | /* | 7 | /* |
8 | A nested linked list increases efficiency of insertions. | 8 | A nested linked list increases efficiency of insertions. |
9 | Depending on the number of timers we have, we might need to have nested linked lists | 9 | Depending on the number of timers we have, we might need to have nested linked lists |
10 | in order to improve insertion efficiency. | 10 | in order to improve insertion efficiency. |
@@ -46,35 +46,37 @@ enum timer_state { | |||
46 | STATE_CALLBACK | 46 | STATE_CALLBACK |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct timer | 49 | struct timer { |
50 | { | ||
51 | enum timer_state state; | 50 | enum timer_state state; |
52 | timer* _prev; | 51 | timer *_prev; |
53 | timer* _next; | 52 | timer *_next; |
54 | timer_callback cb; | 53 | timer_callback cb; |
55 | void* userdata; | 54 | void *userdata; |
56 | uint64_t deadline; | 55 | uint64_t deadline; |
57 | }; | 56 | }; |
58 | 57 | ||
59 | static timer* timer_main_queue; | 58 | static timer *timer_main_queue; |
60 | static timer* timer_us_queue; /* hi-speed queue */ | 59 | static timer *timer_us_queue; /* hi-speed queue */ |
61 | 60 | ||
62 | inline static void timer_dequeue(timer* t, timer** queue) | 61 | inline static void timer_dequeue(timer *t, timer **queue) |
63 | { | 62 | { |
64 | if (t->state == STATE_INACTIVE) return; /* not in a queue */ | 63 | if (t->state == STATE_INACTIVE) return; /* not in a queue */ |
65 | 64 | ||
66 | if (t->_prev) { | 65 | if (t->_prev) { |
67 | t->_prev->_next = t->_next; | 66 | t->_prev->_next = t->_next; |
68 | } else { | 67 | } else { |
69 | *queue = t->_next; | 68 | *queue = t->_next; |
70 | } | 69 | } |
70 | |||
71 | if (t->_next) t->_next->_prev = t->_prev; | 71 | if (t->_next) t->_next->_prev = t->_prev; |
72 | |||
72 | t->state = STATE_INACTIVE; | 73 | t->state = STATE_INACTIVE; |
73 | } | 74 | } |
74 | 75 | ||
75 | static void timer_enqueue(timer* t, timer** queue, timer* prev) | 76 | static void timer_enqueue(timer *t, timer **queue, timer *prev) |
76 | { | 77 | { |
77 | t->state = STATE_ACTIVE; | 78 | t->state = STATE_ACTIVE; |
79 | |||
78 | while (true) { | 80 | while (true) { |
79 | if (!*queue) { | 81 | if (!*queue) { |
80 | t->_next = 0; | 82 | t->_next = 0; |
@@ -104,22 +106,24 @@ void timer_init() | |||
104 | } | 106 | } |
105 | 107 | ||
106 | /* Do not depend on fields being zeroed */ | 108 | /* Do not depend on fields being zeroed */ |
107 | static timer* timer_pool; /* timer_pool is SINGLY LINKED!! */ | 109 | static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */ |
108 | 110 | ||
109 | timer* new_timer(void) | 111 | timer *new_timer(void) |
110 | { | 112 | { |
111 | timer* ret; | 113 | timer *ret; |
114 | |||
112 | if (timer_pool) { | 115 | if (timer_pool) { |
113 | ret = timer_pool; | 116 | ret = timer_pool; |
114 | timer_pool = timer_pool->_next; | 117 | timer_pool = timer_pool->_next; |
115 | } else { | 118 | } else { |
116 | ret = calloc(1, sizeof(struct timer)); | 119 | ret = calloc(1, sizeof(struct timer)); |
117 | } | 120 | } |
121 | |||
118 | ret->state = STATE_INACTIVE; | 122 | ret->state = STATE_INACTIVE; |
119 | return ret; | 123 | return ret; |
120 | } | 124 | } |
121 | 125 | ||
122 | void delete_timer(timer* t) | 126 | void delete_timer(timer *t) |
123 | { | 127 | { |
124 | timer_dequeue(t, &timer_main_queue); | 128 | timer_dequeue(t, &timer_main_queue); |
125 | t->_next = timer_pool; | 129 | t->_next = timer_pool; |
@@ -127,93 +131,99 @@ void delete_timer(timer* t) | |||
127 | timer_pool = t; | 131 | timer_pool = t; |
128 | } | 132 | } |
129 | 133 | ||
130 | void timer_setup(timer* t, timer_callback cb, void* userarg) | 134 | void timer_setup(timer *t, timer_callback cb, void *userarg) |
131 | { | 135 | { |
132 | t->cb = cb; | 136 | t->cb = cb; |
133 | t->userdata = userarg; | 137 | t->userdata = userarg; |
134 | } | 138 | } |
135 | 139 | ||
136 | void* timer_get_userdata(timer* t) | 140 | void *timer_get_userdata(timer *t) |
137 | { | 141 | { |
138 | return t->userdata; | 142 | return t->userdata; |
139 | } | 143 | } |
140 | 144 | ||
141 | static void timer_delay_us(timer* t, int us) | 145 | static void timer_delay_us(timer *t, int us) |
142 | { | 146 | { |
143 | t->deadline += us; | 147 | t->deadline += us; |
144 | timer** queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue; | 148 | timer **queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue; |
145 | timer_dequeue(t, &timer_main_queue); | 149 | timer_dequeue(t, &timer_main_queue); |
146 | timer_enqueue(t, queue, t->_prev); | 150 | timer_enqueue(t, queue, t->_prev); |
147 | } | 151 | } |
148 | 152 | ||
149 | /* Starts the timer so that it's called in sec seconds in the future. | 153 | /* Starts the timer so that it's called in sec seconds in the future. |
150 | * A non-positive value of sec results in the callback being called immediately. | 154 | * A non-positive value of sec results in the callback being called immediately. |
151 | * This function may be called again after a timer has been started to adjust | 155 | * This function may be called again after a timer has been started to adjust |
152 | * the expiry time. */ | 156 | * the expiry time. */ |
153 | void timer_start(timer* t, int sec) | 157 | void timer_start(timer *t, int sec) |
154 | { | 158 | { |
155 | uint64_t newdeadline = current_time() + sec * US_PER_SECOND; | 159 | uint64_t newdeadline = current_time() + sec * US_PER_SECOND; |
156 | if (timer_is_active(t)){ | 160 | |
161 | if (timer_is_active(t)) { | ||
157 | if (t->deadline < newdeadline) { | 162 | if (t->deadline < newdeadline) { |
158 | timer_delay_us(t, newdeadline - t->deadline); | 163 | timer_delay_us(t, newdeadline - t->deadline); |
159 | return; | 164 | return; |
160 | } | 165 | } |
166 | |||
161 | timer_dequeue(t, &timer_main_queue); | 167 | timer_dequeue(t, &timer_main_queue); |
162 | } | 168 | } |
169 | |||
163 | t->deadline = newdeadline; | 170 | t->deadline = newdeadline; |
164 | timer_enqueue(t, &timer_main_queue, 0); | 171 | timer_enqueue(t, &timer_main_queue, 0); |
165 | } | 172 | } |
166 | 173 | ||
167 | /* Stops the timer. Returns -1 if the timer was not active. */ | 174 | /* Stops the timer. Returns -1 if the timer was not active. */ |
168 | int timer_stop(timer* t) | 175 | int timer_stop(timer *t) |
169 | { | 176 | { |
170 | int ret = timer_is_active(t) ? -1 : 0; | 177 | int ret = timer_is_active(t) ? -1 : 0; |
171 | timer_dequeue(t, &timer_main_queue); | 178 | timer_dequeue(t, &timer_main_queue); |
172 | return ret; | 179 | return ret; |
173 | } | 180 | } |
174 | 181 | ||
175 | /* Adds additionalsec seconds to the timer. | 182 | /* Adds additionalsec seconds to the timer. |
176 | * Returns -1 and does nothing if the timer was not active. */ | 183 | * Returns -1 and does nothing if the timer was not active. */ |
177 | int timer_delay(timer* t, int additonalsec) | 184 | int timer_delay(timer *t, int additonalsec) |
178 | { | 185 | { |
179 | if (!timer_is_active(t)) return -1; | 186 | if (!timer_is_active(t)) return -1; |
187 | |||
180 | timer_delay_us(t, additonalsec * US_PER_SECOND); | 188 | timer_delay_us(t, additonalsec * US_PER_SECOND); |
181 | return 0; | 189 | return 0; |
182 | } | 190 | } |
183 | 191 | ||
184 | static uint64_t timer_diff(timer* t, uint64_t time) | 192 | static uint64_t timer_diff(timer *t, uint64_t time) |
185 | { | 193 | { |
186 | if (t->deadline <= time) return 0; | 194 | if (t->deadline <= time) return 0; |
195 | |||
187 | return time - t->deadline; | 196 | return time - t->deadline; |
188 | } | 197 | } |
189 | 198 | ||
190 | /* Returns the time remaining on a timer in seconds. | 199 | /* Returns the time remaining on a timer in seconds. |
191 | * Returns -1 if the timer is not active. | 200 | * Returns -1 if the timer is not active. |
192 | * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */ | 201 | * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */ |
193 | int timer_time_remaining(timer* t) | 202 | int timer_time_remaining(timer *t) |
194 | { | 203 | { |
195 | if (!timer_is_active(t)) return -1; | 204 | if (!timer_is_active(t)) return -1; |
205 | |||
196 | return timer_diff(t, current_time()) / US_PER_SECOND; | 206 | return timer_diff(t, current_time()) / US_PER_SECOND; |
197 | } | 207 | } |
198 | 208 | ||
199 | bool timer_is_active(timer* t) | 209 | bool timer_is_active(timer *t) |
200 | { | 210 | { |
201 | return t->state != STATE_INACTIVE; | 211 | return t->state != STATE_INACTIVE; |
202 | } | 212 | } |
203 | 213 | ||
204 | /* Single-use timer. | 214 | /* Single-use timer. |
205 | * Creates a new timer, preforms setup and starts it. */ | 215 | * Creates a new timer, preforms setup and starts it. */ |
206 | void timer_single(timer_callback cb, void* userarg, int sec) | 216 | void timer_single(timer_callback cb, void *userarg, int sec) |
207 | { | 217 | { |
208 | timer* t = new_timer(); | 218 | timer *t = new_timer(); |
209 | timer_setup(t, cb, userarg); | 219 | timer_setup(t, cb, userarg); |
210 | timer_start(t, sec); | 220 | timer_start(t, sec); |
211 | } | 221 | } |
212 | 222 | ||
213 | /* Single-use microsecond timer. */ | 223 | /* Single-use microsecond timer. */ |
214 | void timer_us(timer_callback cb, void* userarg, int us) | 224 | void timer_us(timer_callback cb, void *userarg, int us) |
215 | { | 225 | { |
216 | timer* t = new_timer(); | 226 | timer *t = new_timer(); |
217 | timer_setup(t, cb, userarg); | 227 | timer_setup(t, cb, userarg); |
218 | t->deadline = current_time() + us; | 228 | t->deadline = current_time() + us; |
219 | t->state = STATE_ACTIVE; | 229 | t->state = STATE_ACTIVE; |
@@ -228,26 +238,30 @@ void timer_poll(void) | |||
228 | /* Handle millisecond timers */ | 238 | /* Handle millisecond timers */ |
229 | while (timer_us_queue) { | 239 | while (timer_us_queue) { |
230 | if (timer_diff(timer_us_queue, time) != 0) break; | 240 | if (timer_diff(timer_us_queue, time) != 0) break; |
231 | timer* t = timer_us_queue; | 241 | |
242 | timer *t = timer_us_queue; | ||
232 | timer_dequeue(t, &timer_us_queue); | 243 | timer_dequeue(t, &timer_us_queue); |
233 | t->cb(0, t->userdata); | 244 | t->cb(0, t->userdata); |
234 | delete_timer(t); | 245 | delete_timer(t); |
235 | } | 246 | } |
236 | 247 | ||
237 | if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) { | 248 | if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) { |
238 | /* time moving backwards is just a sanity check */ | 249 | /* time moving backwards is just a sanity check */ |
239 | prevtime = time; | 250 | prevtime = time; |
240 | 251 | ||
241 | while (timer_main_queue) { | 252 | while (timer_main_queue) { |
242 | if (timer_diff(timer_main_queue, time) != 0) break; | 253 | if (timer_diff(timer_main_queue, time) != 0) break; |
243 | timer* t = timer_main_queue; | 254 | |
255 | timer *t = timer_main_queue; | ||
244 | t->state = STATE_CALLBACK; | 256 | t->state = STATE_CALLBACK; |
245 | int rv = t->cb(t, t->userdata); | 257 | int rv = t->cb(t, t->userdata); |
258 | |||
246 | if (rv != 0) { | 259 | if (rv != 0) { |
247 | timer_dequeue(t, &timer_main_queue); | 260 | timer_dequeue(t, &timer_main_queue); |
248 | delete_timer(t); | 261 | delete_timer(t); |
249 | continue; | 262 | continue; |
250 | } | 263 | } |
264 | |||
251 | if (t->state != STATE_ACTIVE) { | 265 | if (t->state != STATE_ACTIVE) { |
252 | timer_dequeue(t, &timer_main_queue); | 266 | timer_dequeue(t, &timer_main_queue); |
253 | } | 267 | } |
@@ -257,19 +271,20 @@ void timer_poll(void) | |||
257 | 271 | ||
258 | /*** Internal Testing ***/ | 272 | /*** Internal Testing ***/ |
259 | 273 | ||
260 | /* I do not want to expose internals to the public, | 274 | /* I do not want to expose internals to the public, |
261 | * which is why internals testing is done this way. */ | 275 | * which is why internals testing is done this way. */ |
262 | void timer_internal_tests(bool (*assert)(bool, char*)) | 276 | void timer_internal_tests(bool (*assert)(bool, char *)) |
263 | { | 277 | { |
264 | 278 | ||
265 | } | 279 | } |
266 | 280 | ||
267 | void timer_debug_print() | 281 | void timer_debug_print() |
268 | { | 282 | { |
269 | timer* t = timer_main_queue; | 283 | timer *t = timer_main_queue; |
270 | printf("Queue:\n"); | 284 | printf("Queue:\n"); |
285 | |||
271 | while (t) { | 286 | while (t) { |
272 | printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline/US_PER_SECOND, (char*)t->userdata); | 287 | printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline / US_PER_SECOND, (char *)t->userdata); |
273 | t = t->_next; | 288 | t = t->_next; |
274 | } | 289 | } |
275 | } | 290 | } |