next up previous
Next: Performance of User-Space Devices Up: Implementing selectable Devices Previous: Receiving a poll_diff request

Adding select support to pager.c

Given the explanation of poll_diff in the previous sections, it might seem that implementing a selectable device is a daunting task. It's actually not as bad as it sounds--the example code may well be shorter than its explanation!


\begin{Program}
% latex2html id marker 897\listinginput[5]{1}{pager-polldiff.c...
...orting {\tt select(2)} by implementing a
{\tt poll\_diff} callback}\end{Program}

Program 14 shows the implementation of poll_diff in pager.c, which makes its notification interface (/dev/pager/notify) selectable. It is decomposed into a ``top half'' and ``bottom half'' function, exactly as we did for the blocking read implementation in Program 12. First, on lines 1-20, we see the the callback for poll_diff callback itself. It is virtually identical to the read callback in Program 12. The main difference is that it first checks (on line 12) to see if a poll_diff request is already outstanding when a new request comes in. If so, the out-of-date request is destroyed using fusd_destroy, as we described in Section 9.2.

The bottom half is shown on lines 22-46. First, on lines 32-35, it computes the current poll state--if a page has arrived that the client hasn't seen yet, the file is readable; otherwise, it isn't. Next, the driver compares the current poll state with the poll state that the kernel has cached. If the kernel's cache is out of date, the current state is returned to the kernel. Otherwise, it does nothing.

As with the read callback we saw previously, notice that pager_notify_complete_polldiff is called in two different cases:

  1. It is called immediately from the pager_notify_polldiff callback itself. This causes the current poll state to be returned to the kernel immediately when the request arrives if the driver already knows the kernel's state needs to be updated.
  2. It is called when new data arrives that causes the poll state to change. Refer back to Program 12 on page [*]; in the callback that receives new pages, notice on line 45 that the poll_diff completion function is called alongside the read completion function.

With this poll_diff implementation, it is possible for a client to open /dev/pager/notify, and block in a select(2) system call. If another client writes page to /dev/pager/input, the first client's select will unblock, indicating the file has become readable.

For additional example code, take a look at the logring example program we first mentioned in Section 8.3. It also supports select by implementing a similar poll_diff callback.


next up previous
Next: Performance of User-Space Devices Up: Implementing selectable Devices Previous: Receiving a poll_diff request
Jeremy Elson 2003-08-20