86,6 → 86,7 |
thread_t *t = (thread_t *) data; |
waitq_t *wq; |
bool do_wakeup = false; |
DEADLOCK_PROBE_INIT(p_wqlock); |
|
spinlock_lock(&threads_lock); |
if (!thread_exists(t)) |
96,6 → 97,7 |
if ((wq = t->sleep_queue)) { /* assignment */ |
if (!spinlock_trylock(&wq->lock)) { |
spinlock_unlock(&t->lock); |
DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
goto grab_locks; /* avoid deadlock */ |
} |
|
128,6 → 130,7 |
waitq_t *wq; |
bool do_wakeup = false; |
ipl_t ipl; |
DEADLOCK_PROBE_INIT(p_wqlock); |
|
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
147,6 → 150,7 |
|
if (!spinlock_trylock(&wq->lock)) { |
spinlock_unlock(&t->lock); |
DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD); |
goto grab_locks; /* avoid deadlock */ |
} |
|
379,11 → 383,10 |
* Besides its 'normal' wakeup operation, it attempts to unregister possible |
* timeout. |
* |
* @param wq Pointer to wait queue. |
* @param all If this is non-zero, all sleeping threads will be woken up and |
* missed count will be zeroed. |
* @param wq Pointer to wait queue. |
* @param mode Wakeup mode. |
*/ |
void waitq_wakeup(waitq_t *wq, bool all) |
void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode) |
{ |
ipl_t ipl; |
|
390,10 → 393,10 |
ipl = interrupts_disable(); |
spinlock_lock(&wq->lock); |
|
_waitq_wakeup_unsafe(wq, all); |
_waitq_wakeup_unsafe(wq, mode); |
|
spinlock_unlock(&wq->lock); |
interrupts_restore(ipl); |
spinlock_unlock(&wq->lock); |
interrupts_restore(ipl); |
} |
|
/** Internal SMP- and IRQ-unsafe version of waitq_wakeup() |
401,22 → 404,27 |
* This is the internal SMP- and IRQ-unsafe version of waitq_wakeup(). It |
* assumes wq->lock is already locked and interrupts are already disabled. |
* |
* @param wq Pointer to wait queue. |
* @param all If this is non-zero, all sleeping threads will be woken up and |
* missed count will be zeroed. |
* @param wq Pointer to wait queue. |
* @param mode If mode is WAKEUP_FIRST, then the longest waiting thread, |
* if any, is woken up. If mode is WAKEUP_ALL, then all |
* waiting threads, if any, are woken up. If there are no |
* waiting threads to be woken up, the missed wakeup is |
* recorded in the wait queue. |
*/ |
void _waitq_wakeup_unsafe(waitq_t *wq, bool all) |
void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode) |
{ |
thread_t *t; |
count_t count = 0; |
|
loop: |
if (list_empty(&wq->head)) { |
wq->missed_wakeups++; |
if (all) |
wq->missed_wakeups = 0; |
if (count && mode == WAKEUP_ALL) |
wq->missed_wakeups--; |
return; |
} |
|
count++; |
t = list_get_instance(wq->head.next, thread_t, wq_link); |
|
/* |
445,7 → 453,7 |
|
thread_ready(t); |
|
if (all) |
if (mode == WAKEUP_ALL) |
goto loop; |
} |
|