源出處:http://www.startos.com/linux/tips/2011011921499_5.html
/**
* wait_event_interruptible - sleep until a condition gets true
* @wq: the waitqueue to wait on
* @condition: a C expression for the event to wait for
*
* The process is put to sleep (TASK_INTERRUPTIBLE) until the
* @condition evaluates to true or a signal is received.
* The @condition is checked each time the waitqueue @wq is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
*
* The function will return -ERESTARTSYS if it was interrupted by a
* signal and 0 if @condition evaluated to true.
*/
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
3.4 wait_event_interruptible_timeout
#define __wait_event_interruptible_timeout(wq,condition,ret) \
do { \
DEFINE_WAIT(__wait); \
\
for (;;) { \
prepare_to_wait(&wq,&__wait,TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if(!signal_pending(current)) { \
// 當前進程無訊號需要處理
ret = schedule_timeout(ret); \
if(!ret) \
break; //時間片用完喚醒 \
continue; \ .
} \
ret = _ERESTARTSYS; //被訊號喚醒 \
break; \
} \
finish_wait(&wq,&__wait); \
} while (0)
#define wait_event_interruptible_timeout(wq,condition,timeout) \
( { \
long__ret = timeout; \
if(!(condition)) \
__wait_event_interruptible_timeout(wq,condition,__ret); \
__ret; \
})
wait_event_interruptible_timeout()類架構:
4 喚醒系列wake_up
4.1 wake_up 的API
慣例:用 wake_up 喚醒 wait_event;用 wake_up_interruptible 喚醒wait_event_interruptible。很少會需要調用wake_up_interruptible 之外的喚醒函數,但為完整起見,這裡是整個集合:
wake_up(wait_queue_head_t *queue); wake_up_interruptible(wait_queue_head_t *queue); /*wake_up 喚醒隊列中的每個非獨佔等待進程和一個獨佔等待進程。wake_up_interruptible 同樣, 但它跳過處於不可中斷休眠的進程。它們在返回之前, 使一個或多個進程被喚醒、被調度(如果它們被從一個原子上下文調用, 這就不會發生).*/
--------------------------------------------------------------------------------
wake_up_nr(wait_queue_head_t *queue, int nr); wake_up_interruptible_nr(wait_queue_head_t *queue, int nr); /*這些函數類似 wake_up, 除了它們能夠喚醒多達 nr 個獨佔等待者, 而不只是一個. 注意傳遞 0 被解釋為請求所有的互斥等待者都被喚醒*/
--------------------------------------------------------------------------------
wake_up_all(wait_queue_head_t *queue); wake_up_interruptible_all(wait_queue_head_t *queue); /*這種 wake_up 喚醒所有的進程, 不管它們是否進行獨佔等待(可中斷的類型仍然跳過在做不可中斷等待的進程)*/
--------------------------------------------------------------------------------
wake_up_interruptible_sync(wait_queue_head_t *queue); /*一個被喚醒的進程可能搶佔當前進程, 並且在 wake_up 返回之前被調度到處理器。 但是, 如果你需要不要被調度出處理器時,可以使用 wake_up_interruptible 的"同步"變體. 這個函數最常用在調用者首先要完成剩下的少量工作,且不希望被調度出處理器時。*/