In layman ~linux blocking and non-blocking I/O in device drivers

Source: Internet
Author: User
Tags function prototype

Today accidentally received a message, really shocked me, blog Xuan sent me a message, said it is my blog article has characteristics can be out of the book, this simply let me flattered, I just a junior technical house, write blog is also some of their own learning ideas and in the Internet to see some of my blog post and the comprehensive write, In short this gives the additional impetus, lets oneself move forward, hoped and everybody can share some own experience, in the most needs the struggle grade as well as in the technical field alone the process to have the common partner to move forward ~

What is written today is the blocking and non-blocking i/0 in Linux device drivers, what is blocking and non-blocking I/O? In a nutshell, there are two different ways of I/O operations, and the driver can flexibly support both user-space-to-device access methods.

First, the basic concept:

    • Blocking operation: When performing a device operation, if the resource is not available, the process is suspended until the operating conditions are met. The suspended process goes into hibernation and is moved from the scheduler until the condition is satisfied.
    • Non-blocking operation: When a device operation cannot be performed, it is not suspended, it either discards, or queries continuously until it can be manipulated. Non-blocking applications typically use the select system call query to see if a device can be accessed without blocking, eventually triggering the poll function execution in the device driver.

Second, polling operation

Block read one character:

Char buf;fd = open ("/dev/ttys1", O_RDWR), ... res = read (fd,&buf,1); Returns when there is input on the serial port, no input the process hangs sleep if (res = = 1) {  printf ("%c/n", buf);}

Non-blocking read one character:

Char buf;fd = open ("/dev/ttys1", o_rdwr| O_nonblock);//o_nonblock non-blocking identification ... while (read (fd,&buf,1)!=1);//The serial port has no input to return, so the loop reads printf ("%c/n", buf);

Blocking operations are often implemented by waiting queues, and non-blocking operations are implemented by polling. Non-blocking I/O operations typically use the Select () and poll () system call queries in the application layer for non-blocking access to the device. The Select () and poll () system calls will eventually cause the poll () function in the device driver to be called. Here on the queue is not much introduced, we can look at the data structure inside the knowledge point.

The Select () prototype of the application layer is:

int select (int numfds,fd_set *readfds,fd_set *writefds,fd_set *exceptionfds,struct timeval *timeout); The value of Numfds is the highest file description multibyte 1 that needs to be checked, and if select () waits for timeout time, returns if no file descriptor is ready.

The application is:

#inlcude------Main () {  int fd,num;  Char Rd_ch[buffer_len];  Fd_set Rfds,wfds;  Read-Write file Description descriptor  //Open/dev/globalfifo device file  fd=open ("/dev/globalfifo", o_rdwr|) in nonblocking mode O_nonblock);  if (FD! =-1)  {   //fifo clear 0   if (IOCTL (fd,fifo_clear,0) < 0)   {     printf ("IOCTL cmd failed/n");   } While   (1)   {     Fd_zero (&RFDS);     Fd_zero (&WFDS);     Fd_set (FD,&RFDS);     Fd_set (FD,&WFDS);      Select (Fd+1,&rfds,&wfds,null,null);}}  

Here is the poll () function in the device driver, the function prototype is as follows:

static unsigned int poll (struct file *file, struct socket *sock,poll_table *wait)///The first parameter is a file struct pointer, the third parameter is a poll table pointer, This function should do two work
    • Call the Poll_wait () function on the wait queue that may cause changes in the device file status to add the corresponding wait queue header to the poll_table
    • Returns a mask that indicates whether the device can be read without blocking, write access

Here also mention the poll_wait () function, a lot of people will think is the same as the wait_event () function, will block the waiting for something to happen, in fact, this function does not cause blocking, it is the work of the current process to add to the wait list specified by waiting parameter Poll_ In table, the poll_wait () function is prototyped as follows:

static inline void poll_wait (struct file * Filp, wait_queue_head_t * wait_address, poll_table *p) can be seen from the wait queue header Wait_addres s added to the structure in which P is pointing (poll_table)

The typical template for the poll () function in the drive function is as follows:

static unsigned int xxx_poll (struct file *filp,struct socket *sock, poll_table *wait) {unsigned int mask = 0;struct Xxx_dev *dev = filp->private_data;//Gets the device struct pointer ... poll_wait (filp,&dev->r_wait,wait);//Read wait queue header to Poll_tablepoll_ Wait (filp,&dev->w_wait,wait);//write wait queue header to Poll_table...if (...) Readable Mask |= Pollin | Pollrdnorm;if (...) Writable Mask |= Pollout | Pollrdnorm;...return Mask; }

  

Globalfifo driver that supports polling operation

 In Globalfifo's poll () function, first add the r_wait and w_wait of the device structure weight to the waiting queue table, and the GLOBALFIFO device-driven poll () function is as follows:

static unsigned int gloablfif0_poll (struct file *filp,poll_table *wait) {     unsigned int mask = 0;    struct Globalfifo_dev *dev = filp->private_data;    Down (&DEV->SEM);    Poll_wait (filp,&dev->r_wait, wait)  ;    Poll_wait (filp,&dev->r_wait, wait)  ;    if (Dev->current_len! = 0)    {          Mask |= Pollin | Pollrdnorm;      }    if (Dev->current_len! = globalfifo_size)    {        Mask |= pollout | Pollwrnorm;    }    Up (&dev->sem);    return mask;}

  

Iv. Summary

Blocking and non-blocking operations:

    • Defines and initializes the wait-to-column header;
    • Define and initialize the wait queue;
    • Add the wait queue to the wait queue header
    • Set process state (task_interruptible (can be interrupted by signal) and task_uninterruptible (cannot be interrupted by signal))
    • Calling other processes

Poll Mechanism:

    • Add the wait queue header to Poll_table
    • Returns a mask that indicates whether the device can be read without blocking, write access

All rights reserved, reprint please specify reprint address: http://www.cnblogs.com/lihuidashen/p/4442573.html

In layman ~linux blocking and non-blocking I/O in device drivers

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.