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 | */ |