The "completion port" patch I posted this spring (as a demonstration
only) didn't actually create a thread for each operation. I think
that's overkill, and it sounded like most people agreed with that.
Instead, all the "work" was done by the task (thread or process) that
was polling the completion port.
One task would call read() or write(), which would return immediately
with EINPROGRESS. The kernel would queue the request with the
completion port and then forget about it. Another user task would
sit on the completion port, either in read() or select/poll, where
it's basically sitting on the wait queue for the operations.
I used the same hooks used by SIGIO to do the completion. The
network code does some callbacks when read or write buffer space is
availible, so the completion port code would "wake up" the user task
that was waiting on I/O. It would then scan the list and directly
call read()/write() on the sockets that were ready.
There are picky issues (a write() probably shouldn't be considered
complete until it's left the machine -- not just when it gets written
into the kernel network buffers) but the overall concept seemed to
work. What's really happening is that one task requests an I/O
operation and another task actually *does* the task while it's
waiting for the completion notification.
One a side note, signals don't tend to work for large-scale projects
because there are only N signals. If several libraries need to do
async I/O using signals, they would have to coordinate somehow to
pick which signal each will use in place of SIGIO... and that's
assuming we have the option of choosing another signal besides
SIGIO (do we? or does Linux only support SIGIO for this?)
robey
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu