/trunk/kernel/generic/include/synch/waitq.h |
---|
40,8 → 40,10 |
#include <synch/synch.h> |
#include <adt/list.h> |
#define WAKEUP_FIRST 0 |
#define WAKEUP_ALL 1 |
typedef enum { |
WAKEUP_FIRST = 0, |
WAKEUP_ALL |
} wakeup_mode_t; |
/** Wait queue structure. */ |
typedef struct { |
70,8 → 72,8 |
extern ipl_t waitq_sleep_prepare(waitq_t *wq); |
extern int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags); |
extern void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl); |
extern void waitq_wakeup(waitq_t *wq, bool all); |
extern void _waitq_wakeup_unsafe(waitq_t *wq, bool all); |
extern void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode); |
extern void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode); |
extern void waitq_interrupt_sleep(struct thread *t); |
#endif |
/trunk/kernel/generic/src/synch/waitq.c |
---|
384,10 → 384,9 |
* 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 mode Wakeup mode. |
*/ |
void waitq_wakeup(waitq_t *wq, bool all) |
void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode) |
{ |
ipl_t ipl; |
394,7 → 393,7 |
ipl = interrupts_disable(); |
spinlock_lock(&wq->lock); |
_waitq_wakeup_unsafe(wq, all); |
_waitq_wakeup_unsafe(wq, mode); |
spinlock_unlock(&wq->lock); |
interrupts_restore(ipl); |
406,21 → 405,26 |
* 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 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); |
/* |
449,7 → 453,7 |
thread_ready(t); |
if (all) |
if (mode == WAKEUP_ALL) |
goto loop; |
} |
/trunk/kernel/generic/src/proc/scheduler.c |
---|
411,7 → 411,8 |
DEADLOCK_THRESHOLD); |
goto repeat; |
} |
_waitq_wakeup_unsafe(&THREAD->join_wq, false); |
_waitq_wakeup_unsafe(&THREAD->join_wq, |
WAKEUP_FIRST); |
spinlock_unlock(&THREAD->join_wq.lock); |
THREAD->state = Undead; |
/trunk/kernel/generic/src/ipc/ipc.c |
---|
163,7 → 163,7 |
spinlock_lock(&callerbox->lock); |
list_append(&call->link, &callerbox->answers); |
spinlock_unlock(&callerbox->lock); |
waitq_wakeup(&callerbox->wq, 0); |
waitq_wakeup(&callerbox->wq, WAKEUP_FIRST); |
} |
/** Answer message, that is in callee queue |
205,7 → 205,7 |
spinlock_lock(&box->lock); |
list_append(&call->link, &box->calls); |
spinlock_unlock(&box->lock); |
waitq_wakeup(&box->wq, 0); |
waitq_wakeup(&box->wq, WAKEUP_FIRST); |
} |
/** Send a asynchronous request using phone to answerbox |