The wait_event () function is often used to block the current running process to see how to implement the wait_event () function in the Linux kernel.
First, we will introduce several macro-defined functions:
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)
Therefore, define_wait (name) defines a wait_queue_t struct and hooks it with the currently running process, at the same time, it defines the processing function autoremove_wake_function () after the current process is awakened ().
Wait_event () function implementation:
# DEFINE _ wait_event (WQ, condition )\
Do {\
Define_wait (_ Wait); \ defines and initializes a 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 () function implementation:
# 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 ;)
Detailed description of wait_event () function set