Rev 2131 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2131 | Rev 2308 | ||
|---|---|---|---|
| Line 84... | Line 84... | ||
| 84 | void waitq_timeouted_sleep(void *data) |
84 | void waitq_timeouted_sleep(void *data) |
| 85 | { |
85 | { |
| 86 | thread_t *t = (thread_t *) data; |
86 | thread_t *t = (thread_t *) data; |
| 87 | waitq_t *wq; |
87 | waitq_t *wq; |
| 88 | bool do_wakeup = false; |
88 | bool do_wakeup = false; |
| - | 89 | DEADLOCK_PROBE_INIT(p_wqlock); |
|
| 89 | 90 | ||
| 90 | spinlock_lock(&threads_lock); |
91 | spinlock_lock(&threads_lock); |
| 91 | if (!thread_exists(t)) |
92 | if (!thread_exists(t)) |
| 92 | goto out; |
93 | goto out; |
| 93 | 94 | ||
| 94 | grab_locks: |
95 | grab_locks: |
| 95 | spinlock_lock(&t->lock); |
96 | spinlock_lock(&t->lock); |
| 96 | if ((wq = t->sleep_queue)) { /* assignment */ |
97 | if ((wq = t->sleep_queue)) { /* assignment */ |
| 97 | if (!spinlock_trylock(&wq->lock)) { |
98 | if (!spinlock_trylock(&wq->lock)) { |
| 98 | spinlock_unlock(&t->lock); |
99 | spinlock_unlock(&t->lock); |
| - | 100 | DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
|
| 99 | goto grab_locks; /* avoid deadlock */ |
101 | goto grab_locks; /* avoid deadlock */ |
| 100 | } |
102 | } |
| 101 | 103 | ||
| 102 | list_remove(&t->wq_link); |
104 | list_remove(&t->wq_link); |
| 103 | t->saved_context = t->sleep_timeout_context; |
105 | t->saved_context = t->sleep_timeout_context; |
| Line 126... | Line 128... | ||
| 126 | void waitq_interrupt_sleep(thread_t *t) |
128 | void waitq_interrupt_sleep(thread_t *t) |
| 127 | { |
129 | { |
| 128 | waitq_t *wq; |
130 | waitq_t *wq; |
| 129 | bool do_wakeup = false; |
131 | bool do_wakeup = false; |
| 130 | ipl_t ipl; |
132 | ipl_t ipl; |
| - | 133 | DEADLOCK_PROBE_INIT(p_wqlock); |
|
| 131 | 134 | ||
| 132 | ipl = interrupts_disable(); |
135 | ipl = interrupts_disable(); |
| 133 | spinlock_lock(&threads_lock); |
136 | spinlock_lock(&threads_lock); |
| 134 | if (!thread_exists(t)) |
137 | if (!thread_exists(t)) |
| 135 | goto out; |
138 | goto out; |
| Line 145... | Line 148... | ||
| 145 | goto out; |
148 | goto out; |
| 146 | } |
149 | } |
| 147 | 150 | ||
| 148 | if (!spinlock_trylock(&wq->lock)) { |
151 | if (!spinlock_trylock(&wq->lock)) { |
| 149 | spinlock_unlock(&t->lock); |
152 | spinlock_unlock(&t->lock); |
| - | 153 | DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
|
| 150 | goto grab_locks; /* avoid deadlock */ |
154 | goto grab_locks; /* avoid deadlock */ |
| 151 | } |
155 | } |
| 152 | 156 | ||
| 153 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
157 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
| 154 | t->timeout_pending = false; |
158 | t->timeout_pending = false; |
| Line 378... | Line 382... | ||
| 378 | * |
382 | * |
| 379 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
383 | * Besides its 'normal' wakeup operation, it attempts to unregister possible |
| 380 | * timeout. |
384 | * timeout. |
| 381 | * |
385 | * |
| 382 | * @param wq Pointer to wait queue. |
386 | * @param wq Pointer to wait queue. |
| 383 | * @param all If this is non-zero, all sleeping threads will be woken up and |
387 | * @param all If this is WAKEUP_ALL, all sleeping threads will be woken up and |
| 384 | * missed count will be zeroed. |
388 | * missed count will be zeroed. WAKEUP_FIRST wakes up just one thread or |
| - | 389 | * increments the missed count. WAKEUP_ALL_INC_MISSED wakes up all sleeping threads |
|
| - | 390 | * or increments missed_wakeups if there aren't any |
|
| 385 | */ |
391 | */ |
| 386 | void waitq_wakeup(waitq_t *wq, bool all) |
392 | void waitq_wakeup(waitq_t *wq, int all) |
| 387 | { |
393 | { |
| 388 | ipl_t ipl; |
394 | ipl_t ipl; |
| 389 | 395 | ||
| 390 | ipl = interrupts_disable(); |
396 | ipl = interrupts_disable(); |
| 391 | spinlock_lock(&wq->lock); |
397 | spinlock_lock(&wq->lock); |
| Line 400... | Line 406... | ||
| 400 | * |
406 | * |
| 401 | * This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It |
407 | * This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It |
| 402 | * assumes wq->lock is already locked and interrupts are already disabled. |
408 | * assumes wq->lock is already locked and interrupts are already disabled. |
| 403 | * |
409 | * |
| 404 | * @param wq Pointer to wait queue. |
410 | * @param wq Pointer to wait queue. |
| 405 | * @param all If this is non-zero, all sleeping threads will be woken up and |
411 | * @param all If this is WAKEUP_ALL, all sleeping threads will be woken up and |
| 406 | * missed count will be zeroed. |
412 | * missed count will be zeroed. WAKEUP_FIRST wakes up just one thread or |
| - | 413 | * increments the missed count. WAKEUP_ALL_INC_MISSED wakes up all sleeping threads |
|
| - | 414 | * or increments missed_wakeups if there aren't any |
|
| 407 | */ |
415 | */ |
| 408 | void _waitq_wakeup_unsafe(waitq_t *wq, bool all) |
416 | void _waitq_wakeup_unsafe(waitq_t *wq, int all) |
| 409 | { |
417 | { |
| 410 | thread_t *t; |
418 | thread_t *t; |
| 411 | 419 | ||
| 412 | loop: |
- | |
| 413 | if (list_empty(&wq->head)) { |
420 | if (list_empty(&wq->head)) { |
| 414 | wq->missed_wakeups++; |
- | |
| 415 | if (all) |
421 | if (all == WAKEUP_ALL) |
| 416 | wq->missed_wakeups = 0; |
422 | wq->missed_wakeups = 0; |
| - | 423 | else |
|
| - | 424 | wq->missed_wakeups++; |
|
| 417 | return; |
425 | return; |
| 418 | } |
426 | } |
| - | 427 | loop: |
|
| 419 | 428 | ||
| 420 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
429 | t = list_get_instance(wq->head.next, thread_t, wq_link); |
| 421 | 430 | ||
| 422 | /* |
431 | /* |
| 423 | * Lock the thread prior to removing it from the wq. |
432 | * Lock the thread prior to removing it from the wq. |
| Line 442... | Line 451... | ||
| 442 | t->timeout_pending = false; |
451 | t->timeout_pending = false; |
| 443 | t->sleep_queue = NULL; |
452 | t->sleep_queue = NULL; |
| 444 | spinlock_unlock(&t->lock); |
453 | spinlock_unlock(&t->lock); |
| 445 | 454 | ||
| 446 | thread_ready(t); |
455 | thread_ready(t); |
| - | 456 | if (list_empty(&wq->head)) { |
|
| - | 457 | return; |
|
| 447 | 458 | } |
|
| 448 | if (all) |
459 | if (all != WAKEUP_FIRST) |
| 449 | goto loop; |
460 | goto loop; |
| 450 | } |
461 | } |
| 451 | 462 | ||
| 452 | /** @} |
463 | /** @} |
| 453 | */ |
464 | */ |