Linux wait queue and wake up

Source: Internet
Author: User

1. Data structure

1.1 Waiting Queue Header

1 struct __wait_queue_head {2     Lock ; 3     struct List_head task_list; 4 }; 5 struct __wait_queue_head wait_queue_head_t;

Initialize the wait queue header

1 #define __wait_queue_head_initializer (name) {                2     .  Lock        = __spin_lock_unlocked (name.  Lock),        3     . task_list    = {& (name). Task_list, &(name). Task_list} }45#define6     wait_queue_head_t name = __wait_queue_head_ INITIALIZER (name)

1.2 Waiting queue

1typedefstruct__wait_queue wait_queue_t;2typedefint(*wait_queue_func_t) (wait_queue_t *wait, unsigned mode,intSyncvoid*key);3 intDefault_wake_function (wait_queue_t *wait, unsigned mode,intSyncvoid*key);4 5 struct__wait_queue {6Unsignedintflags;7 #defineWq_flag_exclusive 0x018     void*Private;9 wait_queue_func_t func;Ten     structList_head task_list; One};

Initializing the wait queue

1 #define __waitqueue_initializer (name, tsk) {                2     .  Private    = tsk,                        3     . Func        = default_wake_function,            4      . task_list    = {null, NULL}}56#define declare_ Waitqueue (name, tsk)                    7     wait_queue_t name = __waitqueue_initializer (name, tsk)

The task_list waiting queue joins the task_list linked list waiting for the queue header. The wait_queue_func_t is typically assigned the following default handler:

1 int int Sync, 2               void *key)3{4     return try_to_wake_up (curr-> Private , mode, sync); 5 }

1.3 Add/Remove wait queues

1 StaticInlinevoid__add_wait_queue (wait_queue_head_t *head, wait_queue_t *New)2 {3List_add (&New->task_list, &head->task_list);4 }5 6 StaticInlinevoid__remove_wait_queue (wait_queue_head_t *Head,7wait_queue_t *Old )8 {9List_del (&old->task_list);Ten}

2 Waiting events

Call the following four macro wait events, waiting for the first parameter as the waiting queue header to wake up, the second parameter condition must be satisfied, otherwise continue to block.

The difference between wait_event () and wait_event_interruptible () is that the latter can be interrupted by a signal, while the former cannot.

The addition of a timeout macro means that the blocking wait time-out, in Jiffy, is returned when timeout arrives, regardless of whether condition is satisfied.

1 #define 2 #define wait_event_timeout (Wq, condition, timeout)    3#define Wait_event_ Interruptible (Wq, condition)    4#define wait_event_interruptible_timeout (Wq, condition, Timeout

The following is an example of wait_event () to analyze the execution process

1 #defineWait_event (Wq, condition)2  Do {                                    3     if(condition)4          Break; 5 __wait_event (Wq, condition); 6} while(0)7 #define__wait_event (Wq, condition)8  Do {                                    9 define_wait (__wait); Ten                                      One      for (;;) {                             APrepare_to_wait (&WQ, &__wait, task_uninterruptible);  -         if(condition) -              Break;  the schedule ();  -     }                                 -Finish_wait (&WQ, &__wait);  -} while(0)
wait_event (Wq, condition)
wait_event (Wq, condition)-__wait_event (Wq, condition); -define_wait (__wait); -->prepare_to_wait (&WQ, &__wait, task_uninterruptible); -->__add_wait_queue (q, wait);//Add the wait queue to the wait queue header-set_current_state (state); -->schedule ();//switch to another process-be awakened to switch back-->finish_wait (&WQ, &__wait); -__set_current_state (task_running); -->list_del_init (&wait->task_list);//to delete a wake-up wait queue

Note the above define_wait (__WAIT) macro expands as follows

 1   #define  define_wait (name)                        2  wait_queue_t name = {  3 . private  = current,  4 . Func = autoremove_wake_function,  5 . Task_list = List_head_init ((name). Task_list),  6 } 
 1  int  autoremove_wake_function (wait _queue_t *wait, unsigned mode, int  sync, void  *key)  2  { 3  int  ret = default_wake_function (wait, mode, sync, key);  4  5  if   6  list_del_init (&wait-& Gt task_list);  7  return   RET;  8 } 
autoremove_wake_function

3. Wake-up queue

WAKE_UP () can wake up processes in task_uninterruptible and task_interruptible, while wake_up_interruptible can only wake processes that are in task_interruptible.

#define wake_up (x)            __wake_up (x, task_uninterruptible | Task_interruptible, 1, NULL)#define wake_up_interruptible (x)    __wake_up (x, task_interruptible, 1, NULL)

The following is an example of wake_up (),

1 wake_up (x) 2     1 , NULL) 3         0, key); // Wake up all wait queues in the list of waiting queue headers

The key is the __wake_up_common () function

1 /*2 * The core wakeup function. Non-exclusive wakeups (nr_exclusive = = 0) Just3 * Wake everything up. If it ' s an exclusive wakeup (nr_exclusive = = Small +ve4 * number) Then we wake all the non-exclusive tasks and one exclusive task.5  *6 * There is circumstances in which we can try to wake a task which have already7 * Started to run, but isn't in the state task_running. TRY_TO_WAKE_UP () returns8 * Zero in this (rare) case, and we handle it by continuing to scan the queue.9  */Ten Static void__wake_up_common (wait_queue_head_t *q, unsignedintmode, One                  intNr_exclusive,intSyncvoid*key) A { -     structList_head *tmp, *Next; -  theList_for_each_safe (TMP, Next, &q->task_list) { -wait_queue_t *curr =list_entry (TMP, wait_queue_t, task_list); -Unsigned flags = curr->flags; -  +         if(Curr->func (curr, mode, Sync, key) && -(Flags & wq_flag_exclusive) &&!--nr_exclusive) +              Break; A     } at}

The curr->func is a pointer to the Autoremove_wake_function () function.

The wake process is performed specifically in the TRY_TO_WAKE_UP (curr->private, mode, sync) function, which is more complex to wake up and has time to analyze later.

It can be simply understood that the wait queue in 2 wait_event () is woken up to continue execution after the function has been executed.

Linux wait queue and wake up

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.