Dear libev list, Let me ask four theoretic question about what libev could do. These questions are purely academic, as I am not actually planning to write code using anything like these.
Unices have an interface where they can send a signal to the process when a filehandle becomes readable or writable. This interface is edge-triggered, so you don't get repeated signals if you do not consume the input or fill the output buffer. The actual calls for this on linux and bsd are fcntl function F_SETOWN. There are essentially three ways this can help a program. Firstly, the program can use a regular select loop, but as an optimization it can rely on signal handling to interrupt a long sequence of computations early instead of having to call a non-blocking select every so often. Secondly, a program could rely on blocking on signals only (with sigsuspend) instead of having to using select to wait for any of io activity or signals, and then it can try to read or write each file descriptor with non-blocking io. Thirdly, a program can not only block on signals but use sigaction and real-time signals to discover exactly what events happen. My first question is whether this third method could be the base of a backend in libev? There are some difficulties of course: the implementation would be difficult, it might be hard to make it work reliably, and it might not be more efficent than the best current backends. Secondly a seemingly unrelated topic. Some interpreters, most importantly ruby 1.8 use a system where they use signals to implement switching between threads on time slices. This works by setting up a periodic timer signal that sets a flag, and checking this flag quite often but only when it is safe to change to another thread, and if the flag is set they call a scheduler to decide which threads are runnable and which to switch to. There are other programs that use a similar system as well, namely I think ruby 1.9, safe signals in perl 5.8 and later, mz-scheme and the ghc runtime library, but I might not be entirely correct here. The details like when the flag is checked and how threads are switched differ of course. My second question is whether libev could be used in the scheduler of a system like this, to determine which threads to run? Perl Coro can use libev to decide which coro to switch to, but it does not interrupt threads on a timer before they would block. My guess is that libev could work fine in a program like ruby 1.8 but there might be some difficulty I'm not aware of. My third question is whether you could improve some of these threading systems by interrupting a running thread not only when its time slice runs out, but also when an external event (io or timer or anything else) makes another thread runnable? This could be implemented by using the above mentioned F_SETOWN feature to request signals to be delivered on an io event (and similarly setting up alarm signals for the next timer event), and making these signals set that flag as well. This could, I think, decrease latency. Of course, some care should be taken not to let a thread starve others by arranging external events to switch back to it, but this is not unsolvable. Note that something similar is already done in such systems for internal events: a function can yield its time to another thread it has just made runnable as an optimization. My fourth question applies only if the answer to the previous two is yes, namely whether in this case libev itself could arrange for the io and alarm signals to be sent on events the program is watching? This way the program would have to register the event a thread is blocking on, and then libev would use this both to determine which thread can be ran next and to set the thread interrupt flag early. Thanks in advance for any insights, Ambrus _______________________________________________ libev mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
