LWN.net Logo

Edge-triggered interfaces are too difficult?

Edge-triggered interfaces are too difficult?

Posted Mar 15, 2003 6:17 UTC (Sat) by IkeTo (subscriber, #2122)
In reply to: Edge-triggered interfaces are too difficult? by dank
Parent article: Edge-triggered interfaces are too difficult?

> for (;;) {
> get next event on any monitored fd
> handle that event
> }

Is that exactly the same code the parent says might ends up in race condition? In particular, what should happen if an event arrives exactly at the time *after* you handle all events and before you start another monitoring? It seems like that to resolve this race, the kernel may keep a "marker" to know whether an unreported event has occurred. Then we have another problem that the user may get the event during the "handle that event" phase. And the kernel need to check that the "marker" is real before returning to the user. While solvable, it seems not much less work compared to level triggered interface.

On the other hand, is the user-land side really "a piece of cake" compared to level triggered semantics? You need exactly the same code, except that in the "handle that event" part the program can read any event as oppose to read all events?


(Log in to post comments)

Edge-triggered interfaces are too difficult?

Posted Mar 16, 2003 8:07 UTC (Sun) by Ross (subscriber, #4065) [Link]

By "edge triggered" they don't mean that you don't get an event if you don't check at the right time. They mean that you only get told about an event once, rather than every time.

So, if data arrived right after you checked the socket, you wouldn't know about the new event. No problem. You would be notified about it next time you checked.

I don't understand dneto's example at all.

A well-written select() application will already treat notifications like one-time events and do as much input as possible. Not doing so just means more round-trips through the event loop.

Edge-triggered interfaces are too difficult?

Posted Mar 16, 2003 9:04 UTC (Sun) by IkeTo (subscriber, #2122) [Link]

> So, if data arrived right after you checked the socket, you
> wouldn't know about the new event. No problem. You would be
> notified about it next time you checked.

I've made it rather clear in my last post that this is doable, although not exactly easy. Do you notice what the kernel must do, under the current device driver interface, for this whole thing to work like this? Let's have a short account:

1. When an event occurs in the hardware, the device driver calls poll_wait() to tell the kernel that some event has occurred.

2. The kernel now call the poll() method of the device driver---no matter whether anybody is calling select right now! Otherwise a race condition might occur.

3. The kernel must remember what event occurred, so that if select is called later, it can be returned right away.

4. When select is called, the remembered events must be checked, and if they are the ones the user is waiting for, they must be returned without waiting for the device to call poll_wait() again.

5. When a user actually do a read, write or anything that affect the events (say ioctl()), the poll() method must be called again to update the current status of the device. Otherwise the device may report a "change of readability" event even though the event is related to something that occurred before the last read. Alternatively, in the above point, the select call must call poll() to confirm that the events are still there before returning to the user.

Who in the business of OS development will write such an interface when in fact a level triggered interface requires...

1. On select, the poll() method of the device is called to see if the event waited for is already happening, and if so return right away. Otherwise it wait until the device driver calls poll_wait(), and repeat.

2. When hardware event occurs, the device driver will call poll_wait(), and at this time everybody waiting on poll_wait() will be woken up.

..., and that's it?! The interface might make sense on an interface like epoll or even poll, where the kernel is adviced that the user might call poll() on a set of fds. Then it might reduce the number of times that the kernel needs to call the poll() method of the device driver. But for select(), where the user can suddenly call, and after each invocation nothing is left in the kernel, it seems stupid.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds