Linux wait queue and Linux wait queue header relationship-do not understand Linux driver blocking operations can look at __linux

Source: Internet
Author: User

The waiting queue of Linux kernel is based on the double cyclic list, which is closely combined with the process scheduling mechanism, and can be used to realize the core asynchronous event notification mechanism.

In this list, there are two types of data structures: The waiting queue header (wait_queue_head_t) and the Wait queue item (wait_queue_t). Both the wait queue header and the Wait queue item contain a list_head type of domain as a "join". It is linked to a list of double linked lists and the tast of the waiting process. You can see it clearly from the picture above. So we know that if you want to implement a wait queue, there must be two parts first. Queue headers and queue items. Let's look at their data structure.[CPP] View Plain copy print?  1. struct list_head {      2.     struct  list_head *next, *prev;      3. };       4. struct __wait_queue_head {      5.      spinlock_t lock;      6.     struct list_head  task_list;      7. };      8. typedef struct  __wait_queue_head wait_queue_head_t;      9. struct __wait_queue  {     10.     unsigned int flags;      11.  #define  WQ_FLAG_EXCLUSIVE    0x01     12. The      void *private;//2.6 version uses a void pointer, and the previous version is struct task_struct * task;     13.                    //is actually in use, still assign the private value as task     14.      wait_queue_func_t func;     15.      struct list_head task_list;     16. };    

So the queue header and the queue item are connected through the List_head, List_head is a bidirectional linked list, has the widespread application in the Linux kernel. And there's a lot of manipulation of it in list.h.

2. Initialization of column headers and queue items:
wait_queue_head_t My_queue;

Init_waitqueue_head (&my_queue);

directly defined and initialized. The Init_waitqueue_head () function initializes the spin lock to an unlocked, waiting for the queue to be initialized to an empty bidirectional circular chain.

Declare_wait_queue_head (My_queue);

Defined and initialized

3. Define wait Queues: Declare_waitqueue (Name,tsk); [CPP] view plain copy print? 1.  #define    DECLARE_WAITQUEUE (Name,   tsk)         /      2. wait_queue_t   name      =__waitqueue_initializer (Name,   tsk)       3.       4.  #define    __waitqueue_initializer (Name,   tsk)     {         task:     tsk,         task_list:  {  NULL,   NULL    },  __waitqueue_debug_ini (name)}     

Its explanation is:
The wait queue item is initialized to the corresponding task structure through the Declare_waitqueue macro, and the associated pointer for the connection is set to null. The debugging-related code is added.
The process joins itself into a waiting queue by performing the following steps:
1) Call Declare_waitqueue () to create an item that waits for the queue;
2) call Add_wait_queue () to add yourself to the wait queue. The queue wakes up when the process waits for the condition to be satisfied. Write the relevant code elsewhere, and when the event occurs, the peer queue performs the WAKE_UP () operation.
3) Change the process state to: task_interruptible or task_uninterruptible.
4 If the state is set to task_interruptible, the signal wakes the process. That is, pseudo wake (Wake is not due to the occurrence of the event), so check and process the signal.
5 Check whether the condition is true, no need to hibernate, if not true, call scheduled ().
6 when the process is awakened, it checks to see if the condition is true again. Really quit the loop, otherwise call scheduled () again and repeat this step.
7 after the condition is satisfied, the process sets itself to task_running and exits by Remove_wait_queue ().

4. (from the waiting queue header) to add/remove the wait queue

(1) Add_wait_queue () function: (2) Remove_wait_queue () function:

5. Waiting for events: (conditional sleep)

1) wait_event () macro:[CPP] View Plain copy print?  1.  #define  wait_event (wq, condition)  /       2.        3. do { /       4. if  ( Condition)  /       5. break; /        6. __wait_event (wq, condition); /       7. } while  (0)        8.        9.  #define  __wait _event_timeout (Wq, condition, ret)  /      10.       11. do { /      12. define_wait (__wait); /       13. /      14. for  (;;)  { /      15. prepare_to_wait (&wq, &__wait, task_ UninterruptibLE); /      16. if  (condition)  /      17.  break; /    
What schedule does is replace the current process with a process. ret = schedule_timeout (ret); /19. if (!ret)/20. Break /21. }/22. Finish_wait (&wq, &__wait); /23. } while (0)
Sleep in the waiting list until condition is true. During the waiting period, the process is placed task_uninterruptible into sleep until the condition variable becomes true. Each time the process is awakened, the value of the condition is checked.

(2) Wait_event_interruptible () function:

The difference from wait_event () is that the current process is set to the task_interruptible state during the wait process. Every time you wake up, check to see if the condition is true, or if it is true, check if the process is awakened by a signal, Returns a-erestartsys error code. Returns 0 if the condition is true.

(3) Wait_event_timeout () macro:

Similar to Wait_event (). However, if the given sleep time is negative, return immediately. If awakened during sleep, and the condition is true, returns the remaining sleep time, otherwise continues sleep until it reaches or exceeds a given amount of sleep, and then returns 0.

(4) Wait_event_interruptible_timeout () macro:

Similar to Wait_event_timeout (), but returns the Erestartsys error code if interrupted during sleep.

(5) wait_event_interruptible_exclusive () macro

Same as wait_event_interruptible (), but the process of the sleep is a mutex process.

6. Wake-up Queue:

(1) wake_up () function:

Wakes up waiting queues. Can awaken processes in task_interruptible and task_uninteruptible states, and wait_event/wait_event_timeout in pairs.

2 wake_up_interruptible () function: #define WAKE_UP_INTERRUPTIBLE (x) __wake_up (x, task_interruptible, 1, NULL)

and Wake_up () The only difference is that it can only wake up the task_interruptible state of the process., with Wait_event_interruptible/wait_event_interruptible_timeout/wait_ Event_interruptible_exclusive used in pairs.

Task_interruptible, allowing it to be awakened by sending signal (the sleep state can be interrupted);

Task_uninterruptible, do not receive any Singal

7. Sleep on waiting queues: (unconditional sleep, old kernel use, new kernel recommended)

(1) sleep_on () function:

The function is to define a waiting queue (wait), add the current process to the waiting queue (wait), and then place the status of the current process as task_uninterruptible and add the waiting queue (wait) to the wait queue header (q). It is then suspended until the resource is available to be awakened from the waiting queue header (q) and removed from the wait queue header. The process cannot be awakened by a signal while it is suspended waiting for a resource.

(2) Sleep_on_timeout () function:

The difference from the sleep_on () function is that when the function is invoked, a resource that does not have a wait is returned within a specified time (timeout). is actually called the Schedule_timeout () function implementation. It is worth noting that if the given sleep time (timeout) is less than 0, you will not sleep. The function returns the actual sleep time.

(3) interruptible_sleep_on () function:

The only difference between this function and the sleep_on () function is to place the state of the current process as Task_interruptinle, which means that it wakes up if the process receives a signal.

(4) Interruptible_sleep_on_timeout () function:

Similar to the Sleep_on_timeout () function. The process may be awakened by a signal interruption during sleep or when the waiting time arrives, or it may be the time of waiting to arrive.

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.