Asynchronous notifications and asynchronous I/O for Linux kernel development (I)

Source: Internet
Author: User

"Mr. Wang, I have heard of icing on the cake." I patted the king's head and said.

"You are also icing on the cake. I am a long bag on your head for the last few things you mentioned." Mr. Wang glared at me angrily.

"Ah, why? I also deliberately rejected MM's month and took the time to tell you something advanced. It seems that it is not working now," I was surprised. "Well, this time I will tell you something that is related to the frontend, isn't it a icing on the cake? ".

"Well, that's what I plan to do. I just don't mean to say that. What are you talking about today ?" Wang's dark eyes finally flashed. (Why is it so uncomfortable? what is it like? haha)

Let's get down to the truth. Today we will talk about Linux device drivers.ProgramAsynchronous notification and asynchronous I/O ."

Mr. Wang, the frontend does not talk about blocking or non-blocking access, and the poll () function provides a better mechanism for solving device access. So through the cooperation of the entire asynchronous notification mechanism, it will complement each other and the icing on the cake.

What isAsynchronous notification: It is very simple. Once the device is ready, it actively notifies the application. In this case, the application does not need to query the device status.Is this the concept of interruption often mentioned in the hardware ". Comparison above

The accurate statement is actually called "signal-driven asynchronous I/O", and the signal is a simulation of the interrupt mechanism at the software level.

"Mr. Wang, I will give you a chance to show you the differences between this and the front .."

"Well, I understand this,Blocking I/O means waiting until the device can access and re-access. Non-blocking I/O means using poll () to check whether the device can access the device. asynchronous notification means that the device notifies the application itself.

Accessible." Looking at Wang's smart eyes and clear thoughts, I can't help but smile with encouragement.

I just want to emphasize that the above three methods have no advantages or disadvantages and should be chosen based on different application scenarios.

When it comes to signals, in applications, you can use the signal () function to set the corresponding signal processing function to capture the signal (but also capture it, isn't it a processing. The function prototype is

Void (* signal (INT signo, void (* func) (INT)It looks hard, not just for you, but for me, it's okay. Here is an example:

  Void Sigterm_handler ( Int Signo ){ Char Data [max_len]; Int Len; Len = Read (Stdin_fileno, & Data, max_len); Data [Len] = 0; Printf ("Input available: % s \ n ", Data ); Exit (0 );} Int Main ( Void ){ Int Oflags; // Start the signal Driving Mechanism  Signal (Sigio, sigterm_handler); fcntl (records, f_setown, getpid (); oflags = fcntl (records, f_getfl); fcntl (stdin_fileno, f_setfl, oflags | fasync ); // Create an endless loop to prevent program termination  While (1 ); Return 0 ;}
Read this sectionCodeI know what it means. I don't know much about it. Let's move on. In order for a user to process a device release signal in the user space, it must complete three jobs:
 
1) Use the f_setown control command to set the device file owner to this process so that signals sent from the device driver can be received by this process.
 
2) use the f_setflio control command to set the device file to support fasync, that is, asynchronous notification mode.
 
3) connect signals and signal processing functions through signal.
 
Of course, if you know about the Linux/Unix signal mechanism, you may ask why you didn't say the sigaction function. In fact, it doesn't matter. It's almost helpful. If you want to know it, read p261.
 
With the signal sending, the signal must be released:
 
In the asynchronous notification interaction between the device driver and the application, it is not enough to capture the signal only on the application side, because the source of the signal is not on the driver side, therefore, the device driver must release the signal at the right time.
 
To enable the device to support the asynchronous notification mechanism, the driver involves three operations:
 
1) The f_setown command is supported. You can set filp-> f_owner to the corresponding process ID in the command processing. However, this task has been completed by the kernel, and the device driver does not need to handle it.
 
2) The f_setfl command is supported. Whenever the fasync flag changes, the fasync () function in the driver will be executed. Therefore, the driver must implement the fasync () function.
 
3) when the device resources are available, call the kill_fasync () function to stimulate the corresponding signal.
 
The three steps in the driver correspond to the application one by one. For example:
 
 

Asynchronous notification programming in device drivers is relatively simple. It mainly involves some data structures and two functions:

Data Structure: fasync_struct Structure

Function: 1) int fasync_helper (int fd, struct file * filp, int mode, struct fasync_struct ** FA) for processing fasync flag changes );

2) void kill_fasync (struct fasync_struct ** FA, int Sig, int band) for signal release );

Like other device drivers, fasync_struct is generally placed in the device structure. Below is a typical template:

 
StructXxx_dev {StructCdev ;...StructFasync_struct * async_queue;// Asynchronous struct}

In the drive fasync () function, you only need to simply take the three parameters of this parameter and the pointer of the fasync_struct struct pointer as the fourth parameter and pass it to the fasync_helper function. below is a typical template:

  static   int  xxx_fasync ( int  FD,  struct  file * filp,  int  mode) { struct  xxx_dev * Dev = filp-> private_data;  return  fasync_helper (FD, filp, mode, & Dev-> async_queue);} Once the device resources are available, call kill_fasync () to release the sigio signal. When readable, set the third parameter to poll_in, when writing, the third parameter is set to poll_out. Below is a typical template for releasing signals: 
StaticSsize_t xxx_write (StructFile * filp,Const Char_ User * Buf, size_t count, loff_t * f_ops ){StructXxx_dev * Dev = filp-> private_data ;....// Generate asynchronous SignalIf(Dev-> async_queue) {kill_fasync (& Dev-> async_queue, sigio, poll_in );}..}
Finally, when the file is closed, that is, in the device-driven release function, the device-driven fasync () function should be called to delete the file from the list of asynchronous notifications, below is a typical template of the device-driven release function:
Static IntXxx_release (StructInode * inode,StructFile * filp ){StructXxx_dev * Dev = filp-> private_data;// Delete the file from the asynchronous notification listXxx_fasync (-1, filp, 0 );...Return0 ;}

 

"Wait, I know you understand. You want to give me an example. I know what you mean. It doesn't matter. I will make up for it next time ." Without waiting for Mr. Wang, I immediately blocked her. "You, I don't know yet .."

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.