在对当前的运行的进程进行阻塞时经常会用到wait_event()这个函数,来看看linux内核中时如何实现wait_event()这个函数的。
先介绍几个宏定义函数:
1. #define DEFINE_WAIT_FUNC(name, function) \
wait_queue_t name = { \
.private = current, \
.func = function, \
.task_list = LIST_HEAD_INIT((name).task_list),\
}
2. #define DEFINE_WAIT(name) \
DEFINE_WAIT_FUNC(name, autoremove_wake_function)
3. #define init_wait(name) \
do{ \
(name)->private = current;\
(name)->func = autoremove_wake_function; \
INIT_LIST_HEAD(&name->task_list);
}while(0)
因此 DEFINE_WAIT(name)定义了一个wait_queue_t结构体,并且将其与当前正在运行的进程进行挂钩,同时定义了当前这个进程在被唤醒以后所做的处理函数 autoremove_wake_function()。
wait_event()函数的实现:
#define __wait_event(wq, condition) \
do{ \
DEFINE_WAIT(__wait); \ 定义并初始化了一个wait_queue_t
for(;;) \
{ \
prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);\
if(condition) \
break; \
schedule(); \
}
finish_wait(&wq, &__wait); \
}while(0)
#define wait_event(wq, condition) \
do{ \
if(condition) \
break; \
__wait_event(wq, condition); \
}while(0)
wait_event_timeout()函数的实现:
#define __wait_event_timeout(wq,condition,ret) \
do{ \
DEFINE_WAIT(__wait); \
for(;;) \
{ \
prepare_to_wait(&wq,&__wait, TASK_UNINTERRUPTIBLE); \
if(conditon) \
break; \
ret = schedule_timeout(ret); \
if(!ret) \
break; \
}
finish_wait(&wq, &__wait); \
}while(0)
#define wait_event_timeout(wq, conditon, timeout) \
( long __ret = timeout;\
if(!condition) \
__wait_event_timeout(wq, conditon, __ret); \
__ret;)