Blocking sleep implementation mechanism and blocking sleep Mechanism

Source: Internet
Author: User

Blocking sleep implementation mechanism and blocking sleep Mechanism

Before looking at the implementation mechanism of blocking sleep, let's look at the waiting queue that is widely used in the kernel.
The waiting queue of the Linux kernel is a double-loop linked list structure, which is closely integrated with the process scheduling mechanism and can be used to implement the core asynchronous event notification mechanism. It has two data structures: waiting queue header (wait_queue_head_t) and waiting queue item (wait_queue_t ). Both the waiting queue header and the waiting queue item contain a list_head (double-stranded table ). Use such a double-stranded table to link the waiting process.
  
The data structure of the two is as follows:

Struct _ wait_queue_head {spinlock_t lock; // spin lock to achieve mutually exclusive access to the queue struct list_head task_list; // bidirectional cyclic linked list to store the waiting process .}; Typedef struct _ wait_queue_head train; struct _ wait_queue {unsigned int flags; void * private; inclufunc; struct list_head task_list;}; typedef struct _ wait_queue wait_queue_t;

   

We know that IO is blocked by default (unless O_NONBLOC is set). If a process calls read but no data is available, the process must be blocked. this process is immediately awakened when data reaches and the data is returned to the caller. Otherwise, if a process calls write and has no space in the buffer, the process must be blocked, and it must be in a different waiting queue than the one used for read. when some data is written to the hardware device and the space in the output buffer becomes idle, the process is awakened and the write call is successful.

Here is an example of a read operation:

Static ssize_t scull_p_read (struct file * filp, char _ user * buf, size_t count, loff_t * f_pos) {struct scull_pipe * dev = filp-> private_data; if (down_interruptible (& dev-> sem) // lock return-ERESTARTSYS; while (dev-> rp = dev-> wp) // nothing readable {up (& dev-> sem); // unlock if (filp-> f_flags & O_NONBLOCK) // return-EAGAIN immediately in non-blocking mode; // block access and wait for sleep until the read conditions are met. If (wait_event_interruptible (dev-> inq, (dev-> rp! = Dev-> wp) return-ERESTARTSYS; if (down_interruptible (& dev-> sem) // re-lock return-ERESTARTSYS;} // read data. ...... Up (& dev-> sem); wake_up_interruptible (& dev-> outq); return count ;}

From the preceding example, we can see that wait_event_interruptible () is called to implement blocking and waiting. Let's take a look at the wait_event_interruptible () implementation.

# Define wait_event_interruptible (wq, condition) ({int _ ret = 0; if ((! Condition) _ wait_event_interruptible (wq, condition, _ ret); _ ret;}) # define _ wait_event_interruptible (wq, condition, _ ret) do {DEFINE_WAIT (_ wait); // defines the waiting queue _ wait for (;) {prepare_to_wait (& wq, & __ wait, TASK_INTERRUPTIBLE ); // Add the wait queue _ wait to the wq-headed waiting queue linked list, and set the process status to TASK_INTERRUPTIBLE if (condition) // if the condition is met, the break is thrown out; if (! Signal_pending (current) {// schedule () is not awakened by the signal; // discard the CPU and schedule other processes to execute continue;} ret =-ERESTARTSYS; break ;} finish_wait (& wq, & __ wait); // remove the wait queue _ wait from the waiting queue linked list pointed by the wq header, set the Process status to TASK_RUNNING} while (0)

To sum up, the steps for blocking sleep are generally:
1) assign and initialize a wait_queue_t structure, and then add it to the correct waiting queue. when everything is in place, the person in charge of wakeup can find the correct process.
2) set the process status to mark it as sleep (TASK_UNINTERRUPTIBLE, TASK_INTERRUPTIBLE)
3) call schedule () to let out the CPU.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.