Rev 2336 | Rev 2421 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2336 | Rev 2416 | ||
---|---|---|---|
Line 121... | Line 121... | ||
121 | } else |
121 | } else |
122 | uptime->useconds += 1000000 / HZ; |
122 | uptime->useconds += 1000000 / HZ; |
123 | } |
123 | } |
124 | } |
124 | } |
125 | 125 | ||
- | 126 | #if defined CONFIG_TIMEOUT_AVL_TREE || \ |
|
126 | #ifdef CONFIG_TIMEOUT_EXTAVL_TREE |
127 | defined CONFIG_TIMEOUT_EXTAVL_TREE |
127 | 128 | ||
128 | /** Clock routine |
129 | /** Clock routine |
129 | * |
130 | * |
130 | * Clock routine executed from clock interrupt handler |
131 | * Clock routine executed from clock interrupt handler |
131 | * (assuming interrupts_disable()'d). Runs expired timeouts |
132 | * (assuming interrupts_disable()'d). Runs expired timeouts |
Line 136... | Line 137... | ||
136 | { |
137 | { |
137 | timeout_t *h; |
138 | timeout_t *h; |
138 | timeout_handler_t f; |
139 | timeout_handler_t f; |
139 | void *arg; |
140 | void *arg; |
140 | count_t missed_clock_ticks = CPU->missed_clock_ticks; |
141 | count_t missed_clock_ticks = CPU->missed_clock_ticks; |
141 | uint64_t *i = &(CPU->timeout_active_tree.basetime); |
142 | uint64_t *i = &(CPU->timeout_active_tree.base); |
142 | uint64_t absolute_clock_ticks = *i + |
143 | uint64_t absolute_clock_ticks = *i + missed_clock_ticks; |
- | 144 | #if defined CONFIG TIMEOUT_AVL_TREE |
|
143 | missed_clock_ticks; |
145 | avltree_node_t *expnode; |
144 | extavltree_node_t *head = &(CPU->timeout_active_tree.head); |
146 | #elif defined CONFIG_TIMEOUT_EXTAVL_TREE |
145 | extavltree_node_t *expnode = head->next; |
147 | extavltree_node_t *expnode; |
- | 148 | #endif |
|
146 | 149 | ||
147 | /* |
150 | /* |
148 | * To avoid lock ordering problems, |
151 | * To avoid lock ordering problems, |
149 | * run all expired timeouts as you visit them. |
152 | * run all expired timeouts as you visit them. |
150 | */ |
153 | */ |
151 | 154 | ||
152 | for (; *i <= absolute_clock_ticks; (*i)++) { |
155 | for (; *i <= absolute_clock_ticks; (*i)++) { |
- | 156 | /* |
|
- | 157 | * Basetime is encreased by missed clock ticks + 1 !! |
|
- | 158 | */ |
|
- | 159 | ||
153 | clock_update_counters(); |
160 | clock_update_counters(); |
154 | spinlock_lock(&CPU->timeoutlock); |
161 | spinlock_lock(&CPU->timeoutlock); |
155 | 162 | ||
- | 163 | /* |
|
- | 164 | * Check whether first timeout in list time out. If so perform callback function and try |
|
- | 165 | * next timeout (more timeouts can have same timeout). |
|
- | 166 | */ |
|
156 | while ((expnode = head->next) != head) { |
167 | while ((expnode = CPU->timeout_active_tree.head.next) != &(CPU->timeout_active_tree.head)) { |
157 | h = extavltree_get_instance(expnode,timeout_t,node); |
168 | h = extavltree_get_instance(expnode,timeout_t,node); |
158 | spinlock_lock(&h->lock); |
169 | spinlock_lock(&h->lock); |
159 | if (expnode->key != *i) { |
170 | if (expnode->key != *i) { |
160 | spinlock_unlock(&h->lock); |
171 | spinlock_unlock(&h->lock); |
161 | break; |
172 | break; |
162 | } |
173 | } |
163 | 174 | ||
- | 175 | /* |
|
- | 176 | * Delete first node in the list and repair tree structure in |
|
- | 177 | * constant time. |
|
- | 178 | */ |
|
- | 179 | #if defined CONFIG TIMEOUT_AVL_TREE |
|
- | 180 | avltree_delete_min(&CPU->timeout_active_tree); |
|
- | 181 | #elif defined CONFIG_TIMEOUT_EXTAVL_TREE |
|
164 | extavltree_delete_min(&CPU->timeout_active_tree); |
182 | extavltree_delete_min(&CPU->timeout_active_tree); |
- | 183 | #endif |
|
165 | 184 | ||
166 | f = h->handler; |
185 | f = h->handler; |
167 | arg = h->arg; |
186 | arg = h->arg; |
168 | timeout_reinitialize(h); |
187 | timeout_reinitialize(h); |
169 | spinlock_unlock(&h->lock); |
188 | spinlock_unlock(&h->lock); |
Line 201... | Line 220... | ||
201 | scheduler(); |
220 | scheduler(); |
202 | } |
221 | } |
203 | } |
222 | } |
204 | } |
223 | } |
205 | 224 | ||
- | 225 | #elif defined CONFIG_TIMEOUT_EXTAVLREL_TREE |
|
- | 226 | ||
- | 227 | /** Clock routine |
|
- | 228 | * |
|
- | 229 | * Clock routine executed from clock interrupt handler |
|
- | 230 | * (assuming interrupts_disable()'d). Runs expired timeouts |
|
- | 231 | * and preemptive scheduling. |
|
- | 232 | * |
|
- | 233 | */ |
|
- | 234 | void clock(void) |
|
- | 235 | { |
|
- | 236 | extavltree_node_t *expnode; |
|
- | 237 | timeout_t *h; |
|
- | 238 | timeout_handler_t f; |
|
- | 239 | void *arg; |
|
- | 240 | count_t missed_clock_ticks = CPU->missed_clock_ticks; |
|
- | 241 | int i; |
|
- | 242 | ||
- | 243 | /* |
|
- | 244 | * To avoid lock ordering problems, |
|
- | 245 | * run all expired timeouts as you visit them. |
|
- | 246 | */ |
|
- | 247 | for (i = 0; i <= missed_clock_ticks; i++) { |
|
- | 248 | clock_update_counters(); |
|
- | 249 | spinlock_lock(&CPU->timeoutlock); |
|
- | 250 | ||
- | 251 | /* |
|
- | 252 | * Check whether first timeout in list time out. If so perform callback function and try |
|
- | 253 | * next timeout (more timeouts can have same timeout). |
|
- | 254 | */ |
|
- | 255 | while ((expnode = CPU->timeout_active_tree.head.next) != &(CPU->timeout_active_tree.head)) { |
|
- | 256 | h = list_get_instance(l, timeout_t, link); |
|
- | 257 | spinlock_lock(&h->lock); |
|
- | 258 | if (expnode->key != 0) { |
|
- | 259 | expnode->key--; |
|
- | 260 | spinlock_unlock(&h->lock); |
|
- | 261 | break; |
|
- | 262 | } |
|
- | 263 | ||
- | 264 | /* |
|
- | 265 | * Delete first node in the list and repair tree structure in |
|
- | 266 | * constant time. Be careful of expnode's key, it must be 0! |
|
- | 267 | */ |
|
- | 268 | extavltree_delete_min(&CPU->timeout_active_tree); |
|
- | 269 | ||
- | 270 | f = h->handler; |
|
- | 271 | arg = h->arg; |
|
- | 272 | timeout_reinitialize(h); |
|
- | 273 | spinlock_unlock(&h->lock); |
|
- | 274 | spinlock_unlock(&CPU->timeoutlock); |
|
- | 275 | ||
- | 276 | f(arg); |
|
- | 277 | ||
- | 278 | spinlock_lock(&CPU->timeoutlock); |
|
- | 279 | } |
|
- | 280 | spinlock_unlock(&CPU->timeoutlock); |
|
- | 281 | } |
|
- | 282 | CPU->missed_clock_ticks = 0; |
|
- | 283 | ||
- | 284 | /* |
|
- | 285 | * Do CPU usage accounting and find out whether to preempt THREAD. |
|
- | 286 | */ |
|
- | 287 | ||
- | 288 | if (THREAD) { |
|
- | 289 | uint64_t ticks; |
|
- | 290 | ||
- | 291 | spinlock_lock(&CPU->lock); |
|
- | 292 | CPU->needs_relink += 1 + missed_clock_ticks; |
|
- | 293 | spinlock_unlock(&CPU->lock); |
|
- | 294 | ||
- | 295 | spinlock_lock(&THREAD->lock); |
|
- | 296 | if ((ticks = THREAD->ticks)) { |
|
- | 297 | if (ticks >= 1 + missed_clock_ticks) |
|
- | 298 | THREAD->ticks -= 1 + missed_clock_ticks; |
|
- | 299 | else |
|
- | 300 | THREAD->ticks = 0; |
|
- | 301 | } |
|
- | 302 | spinlock_unlock(&THREAD->lock); |
|
- | 303 | ||
- | 304 | if (!ticks && !PREEMPTION_DISABLED) { |
|
- | 305 | scheduler(); |
|
- | 306 | } |
|
- | 307 | } |
|
- | 308 | } |
|
- | 309 | ||
- | 310 | ||
206 | 311 | ||
207 | #else |
312 | #else |
208 | 313 | ||
209 | 314 | ||
210 | /** Clock routine |
315 | /** Clock routine |
Line 274... | Line 379... | ||
274 | 379 | ||
275 | if (!ticks && !PREEMPTION_DISABLED) { |
380 | if (!ticks && !PREEMPTION_DISABLED) { |
276 | scheduler(); |
381 | scheduler(); |
277 | } |
382 | } |
278 | } |
383 | } |
279 | - | ||
280 | } |
384 | } |
281 | 385 | ||
282 | #endif |
386 | #endif |
283 | /** @} |
387 | /** @} |
284 | */ |
388 | */ |