Linux System Calls - Using and Implementing Poll
11 Aug 2014Here we try to describe the linux post system call from both the client and the device driver perspective. Implementing post system call can serve as a useful excercise in clarifying lots of introductory device driver and systems programming concepts.
Client side poll
At a basic level the poll system call allows you to wait on several file descriptors for data to become available allowing you perform non-blocking I/O operations on the active file descriptors. As the client for poll one you need to invoke the following system call.
The argument the set of file descriptors to be monitored is specified using the an array of structures of the following form.
The events field is a bit mask of requested events that the application program is interested in. While the revents is a an output parameter filled in by the kernel.
The bits in the events can use predefined definitions in
**
Upon success the poll system call will return the number of structures which have non-zero revents. A value of 0 simply indicates that timeout was reached with no file descriptor ready. A value -1 indicates that an errono was set for us.
Example usage of poll
One of the commonly cited reasons for using poll is the example of a server which needs to serve multiple clients when data becomes available. For our somewhat contrived example however we will use named pipes as a way to exercises our client. For a more detailed account on named pipes see here
We can create a named pipe and write to it with the following commands:
Thus the output of tail shall becomes available to be read from at the read end of the named pipe np.
We can test then by it out
Finally we can write a client with now given multiple file names can poll them for output as and when data becomes available.
Here ufollow is a client program which uses poll system call to open check the file descriptors corresponding to the file names to read data as and when it becomes available.
One wrinkle in all of this is that poll system call always returns success for regular files. Although i am yet to try it inotify can be used to convert regular file descriptors into file descriptors which will work with the poll system call. Allowing us to preserve the regularity of the the poll interface.
Driver side view of Blocking I/O and wait queues.
Driver side implementation of poll system call.
Typically a users request for a poll an a file descriptor is going to get translated into a call into the appropriate driver associated with that file descriptor. Imagine for instance a simple device file occurring in /dev directory on the linux file system. Typically such device file inodes are associated with a major number and minor number as seen in from the following invocation of the ls command.
Here we see that /dev/null device is associated with the major number 1 and the minor number 3. We also notice that that this is the same driver that is used to read and write the memory directly(as witnessed by the shared major number of 1). The ācā at the beginning specifies that the underlying device files are character devices.
Assuming thus that we have created and associated our driver with a major number and minor number appropriately (See LDD3) for details. We now get to the linux kernels internal architecture for simplifying the implementation of the poll system call.
Drivers intending to support the poll system call must start by first implementing
Summary
The primary reference text that I have been using which is tremendously helpful in understanding the implementation of the poll and select interface is the Linux Device Driver Third Edition by the dynamic trio Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman. Available for free here and at Amazon. While the kernel has gone through many modifications since 2.6.10 many parts of the book are still quite relevant and readable. As always any comments or suggestions for improvements are always welcome.