Blocking and non-blocking operations in Linux Device Drivers

Source: Internet
Author: User

「 Blocking and non-blocking definitions 」
A blocking operation means that when a device operation fails to obtain the resource, the process suspends until the operation meets the operational conditions. The suspended process enters the sleep state and is removed from the running queue of the scheduler until the waiting conditions are met.
A non-blocking process does not stop when it cannot perform device operations.
Blocking instances 」
Multiple processes use blocking mechanisms to ensure that other processes can read global variables only after a process has been written.
# Include <linux/module. h> # include <linux/init. h> # include <linux/fs. h> # include <asm/uaccess. h> # include <linux/wait. h> # include <asm/semaphore. h>
MODULE_LICENSE ("GPL ");
# Define MAJOR_NUM 254
Static ssize_t globalvar_read (struct file *, char *, size_t, loff_t *); static ssize_t globalvar_write (struct file *, const char *, size_t, loff_t *);
Struct file_operations globalvar_fops = {read: globalvar_read, write: globalvar_write ,};
Static int global_var = 0; static struct semaphore sem; static wait_queue_head_t outq; // defines the wait queue header static int flag = 0; // blocking condition static int _ init globalvar_init (void)
{Int ret; ret = register_chrdev (MAJOR_NUM, "globalvar", & globalvar_fops); if (ret)
{Printk ("globalvar register failure");} else {printk ("globalvar register success"); init_MUTEX (& sem); init_waitqueue_head (& outq);} return ret ;} static void _ exit globalvar_exit (void)
{Int ret; ret = unregister_chrdev (MAJOR_NUM, "globalvar"); if (ret)
{Printk ("globalvar unregister failure");} else {printk ("globalvar unregister success ");}
Static ssize_t globalvar_read (struct file * filp, char * buf, size_t len, loff_t * off)
{// Wait for the data to obtain if (wait_event_interruptible (outq, flag! = 0) // here, let the calling process enter the suspended state until it is full. // The conditions following the full State are not removed from the suspended state {return-ERESTARTSYS ;} if (down_interruptible (& sem ))
{Return-ERESTARTSYS;} flag = 0; // The blocking condition changes here, meaning that this variable can only be read once at a time, unless a new value is assigned to this // variable again.
If (copy_to_user (buf, & global_var, sizeof (int )))
{Up (& sem); return-EFAULT;} up (& sem); return sizeof (int );}
Static ssize_t globalvar_write (struct file * filp, const char * buf, size_t len, loff_t * off)
{If (down_interruptible (& sem ))
{Return-ERESTARTSYS;} if (copy_from_user (& global_var, buf, sizeof (int )))
{Up (& sem); return-EFAULT;} up (& sem); flag = 1; // The blocking condition changes here, this means that the process that can be suspended can be lifted/* The Notification data can be obtained. The process that previously called the read function has been adjusted to the suspended state, only when one condition is met will it be freed from the pending state. Note that there is no automatic detection condition, or when the condition changes, the kernel is automatically notified to change the state of the process. Instead, we need to call the function to manually wake up the waiting queue. The queue will detect the conditions. If the conditions are met, the process will be lifted. If the conditions are not met, the process will still be blocked.
*/Wake_up_interruptible (& outq); return sizeof (int);} module_init (globalvar_init); module_exit (globalvar_exit );
There is a problem here. The waiting queue may have multiple blocked processes. In this case: 1. Can the subsequent processes be lifted earlier by the previous process?
2. What is the condition detection mechanism of the queue when the function tries to wake up the queue? Are the conditions for checking the process order one by one?
The reference application used to test the driver is: Read program 」
# Include <sys/types. h> # include <sys/stat. h> # include <stdio. h> # include <fcntl. h> main ()
{Int fd, num; fd = open ("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR); if (fd! =-1)
{While (1)
{Read (fd, & num, sizeof (int); // The program will block this statement unless there is an input printf ("The globalvar is % d \ n" for globalvar ", num); // if the input is 0, exit if (num = 0)
{Close (fd); break;} else {printf ("device open failure \ n ");}
Write a program 」
# Include <sys/types. h> # include <sys/stat. h> # include <stdio. h> # include <fcntl. h> main ()
{Int fd, num; fd = open ("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR); if (fd! =-1)
{While (1)
{Printf ("Please input the globalvar: \ n"); scanf ("% d", & num); write (fd, & num, sizeof (int )); // if the input is 0, exit if (num = 0)
{Close (fd); break;} else {printf ("device open failure \ n ");}

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.