The waiting queue mechanism in the Linux kernel is used a lot in driver development. It is mostly used to implement blocking access. The following briefly summarizes the four usages of waiting queues, and I hope it will be helpful to readers.
1. Sleep and wait for a certain condition to occur (sleep when the condition is false):
Sleep mode: wait_event, wait_event_interruptible
Wake-up mode: wake_up (Check whether the condition is true when waking up, if it is false, continue to sleep, and the condition must become true before waking up)
2. Manual sleep mode 1:
1) Create and initialize a waiting queue item
DEFINE_WAIT(my_wait) <==> wait_queue_t my_wait; init_wait(&my_wait);
2) Add the waiting queue item to the head of the waiting queue and set the state of the process
prepare_to_wait(wait_queue_head_t *queue, wait_queue_t *wait, int state)
3) Call schedule() to tell the kernel to schedule other processes to run
4) Schedule returns to complete the subsequent cleanup work
finish_wait()
3. Manual sleep mode two:
1) Create and initialize a waiting queue item:
DEFINE_WAIT(my_wait) <==> wait_queue_t my_wait; init_wait(&my_wait);
2) Add the waiting queue item to the head of the waiting queue:
add_wait_queue
3) Set the process status
__set_current_status(TASK_INTERRUPTIBLE);
4) schedule()
5) Remove the waiting queue item from the waiting queue
remove_wait_queue()
In fact, this sleep mode is equivalent to splitting the second step prepare_to_wait in manual sleep mode one into two steps, namely prepare_to_wait <====>add_wait_queue + __set_current_status, the others are the same.
4. The old version of the sleep function sleep_on(wait_queue_head_t *queue):
To unconditionally sleep the current process on a given waiting queue, this function is highly discouraged because it does not have any protection mechanism against race conditions.