Toy idea: IPC as interrupts
Posted: Sun Jun 11, 2006 6:59 pm
Many microkernels implement hardware interrupts as messages, so after reading the words "L4.Sec models interrupts as messages from ?hardware? threads." a weird idea crossed my mind. In a way, it's not even so different from those Coyotos FCRBs.
So what if, instead of modelling interrupts as messages, one would model messages as interrupts? I only got this idea about 2 minutes ago, but it seems to allow asynchronous transfers, with little global policy, no kernel buffering... and well.. I wonder why nobody has mentioned this...
Teh idea goes like this:
Every thread must have a receive buffer defined. It must be long enough to contain the longest message the thread is willing to receive (otherwise we'll truncate) and it must be accessible to the thread, but that's pretty much it.
When a thread gets a message, the message is copied to that message area, and the thread is interrupted (thrown into something like an interrupt/signal handler). This interrupt handler can check if the message makes sense, discard it if not, and set a new buffer if required. Setting a new buffer and returning from interrupt nicely go into a single syscall, after which we'll unblock the thread if it was waiting for a message.
If processes malloc is interrupt safe, then a new buffer can be allocated using normal malloc, which is nice. And if one combines this with fast userspace-semaphores for queue management in userspace, one can avoid syscall for receives which need not block. A simple server could even serve the whole request directly from the handler, while others could server some requests directly, and queue the rest.
Typical case server invocation cost (at least with higher priority server) would look like this:
1. client syscalls to "send"
2. message is copied to receivers buffer
3. receive thread is interrupted, and scheduled
4. receiver either serves the message (simple case) or queues it (sets new buffer and returns from handler
5. in non-simple case receiver is then scheduled for normal execution
With some additional complexity, one could even avoid the interruption when receiver is waiting for a message, only doing the extra work when queueing is actually required.
Now queueing policy goes out of kernel (should we queue? should we priorize? how much to queue?), transfer is atomic even if we use sender blocking with timeout, it should be possible to avoid multiple copies in most cases.. and so on.
I'd like to emphasize, that while sender would be blocked, and it might timeout, by the time the receiver is interrupted, the message has been transferred already, so the whole thing is atomic.
Ofcourse, by default this stuff would be handled by runtime library. Oh, and now the same mechanism can support things like POSIX signals, which are typically hard to do with IPC.
I'm not sure if I'm going to implement this any time soon, but it does seem like an interesting idea.
Thoughts?
So what if, instead of modelling interrupts as messages, one would model messages as interrupts? I only got this idea about 2 minutes ago, but it seems to allow asynchronous transfers, with little global policy, no kernel buffering... and well.. I wonder why nobody has mentioned this...
Teh idea goes like this:
Every thread must have a receive buffer defined. It must be long enough to contain the longest message the thread is willing to receive (otherwise we'll truncate) and it must be accessible to the thread, but that's pretty much it.
When a thread gets a message, the message is copied to that message area, and the thread is interrupted (thrown into something like an interrupt/signal handler). This interrupt handler can check if the message makes sense, discard it if not, and set a new buffer if required. Setting a new buffer and returning from interrupt nicely go into a single syscall, after which we'll unblock the thread if it was waiting for a message.
If processes malloc is interrupt safe, then a new buffer can be allocated using normal malloc, which is nice. And if one combines this with fast userspace-semaphores for queue management in userspace, one can avoid syscall for receives which need not block. A simple server could even serve the whole request directly from the handler, while others could server some requests directly, and queue the rest.
Typical case server invocation cost (at least with higher priority server) would look like this:
1. client syscalls to "send"
2. message is copied to receivers buffer
3. receive thread is interrupted, and scheduled
4. receiver either serves the message (simple case) or queues it (sets new buffer and returns from handler
5. in non-simple case receiver is then scheduled for normal execution
With some additional complexity, one could even avoid the interruption when receiver is waiting for a message, only doing the extra work when queueing is actually required.
Now queueing policy goes out of kernel (should we queue? should we priorize? how much to queue?), transfer is atomic even if we use sender blocking with timeout, it should be possible to avoid multiple copies in most cases.. and so on.
I'd like to emphasize, that while sender would be blocked, and it might timeout, by the time the receiver is interrupted, the message has been transferred already, so the whole thing is atomic.
Ofcourse, by default this stuff would be handled by runtime library. Oh, and now the same mechanism can support things like POSIX signals, which are typically hard to do with IPC.
I'm not sure if I'm going to implement this any time soon, but it does seem like an interesting idea.
Thoughts?