Now Unix is finally, in 2021, getting a syscall queue construct where I can interact with the kernel asynchronously.
Now Unix is finally, in 2021, getting a syscall queue construct where I can interact with the kernel asynchronously.
So, it will probably happen Soon™, but you're probably still ~2 years out before you can reliably depend on it, I'd say.
The kernel wakes up the user space scheduler when it decides to put the process onto a cpu. The user space scheduler decides which user space thread executes in the kernel thread context that it runs in, and does a user space thread switch (not a full context switch) to it. It's a combination of kernel threads and user space (aka "green") threads.
[1] https://www.phoronix.com/scan.php?page=news_item&px=Google-F...
The sort of thing Go and Rust runtimes try to approximate in a hackish way nowadays. They would both by improved by an appropriate scheduler-activation hook.
Back then the idea didn't gain support. It needed a champion, and nobody cared enough. It seemed unnecessary, complicated. What was done instead seemed to be driven by interests that focused on one kind of task or another, e.g. networking or databases.
It doesn't help that the understandings many people have of performance around asynchronous I/O, stackless and stackful coroutines, userspace-kernel interactions, CPU-hardware interactions and so on are not particularly deep. For example I've met a few people who argued that "async-await" is the modern and faster alternative to threads in every scenario, except for needing N threads to use N CPU cores. But that is far from correct. Stackful coroutines doing blocking I/O with complex logic (such as filesystems) are lighter than async-await coroutines doing the same thing, and "heavy" fair scheduling can improve throughput and latency statistics over naive queueing.
It's exciting to see efficient userspace-kernel I/O scheduling getting attention, and getting better over the years. Kudos to the implementors.
But it's also kind of depressing that things that were on the table 20-25 years ago take this long to be evaluated. It's almost as if economics and personal situations governs progress much more than knowledge and ideas...
It's almost as if economics and personal situations
governs progress much more than knowledge and ideas...
That has always been the case and will probably always be the case.https://web.archive.org/web/20110719052845/http://developers...
So at least one UNIX system had them a while ago.
I've written at least two wrapper libraries for I/O readiness, POSIX signal, file event, and user-triggered event polling that encompass epoll, kqueue, and Solaris Event Ports. Supporting all three is relatively trivial from an API perspective because they work so similarly. In fact, notably all three let you poll on the epoll, kqueue, or Event Port descriptor itself. So you can have event queue trees, which is very handy when writing composable libraries.
I believe both are limited to specific operations, mostly IO, and aren't fully general asynchronous syscall interfaces.
I went through the list of operations supported by `io_uring_enter`. Almost all of them are for IO, the remainder (NOP, timeout, madvise) are useful for supporting IO, though madvise might have some non-IO uses as well. While io_uring could form the basis of a generic async syscall interface in the future, in its current state it most certainly is not.
The article mostly talks about io_uring enabling completion based IO instead of readiness based IO.
AFAIK kqueue also supports completion based IO using aio_read/aio_write together with sigevent.
If you can point to a practical example of a program doing it this way and seeing a performance benefit, I would be curious to see it. I did some googling and didn't really even find any articles mentioning this as possibility.
kqueue is widely considered to be readiness based, just like epoll, not completion based.
What you wrote sounds like an interesting hack, but I'm not sure it counts for much if it is impractical to use.
Now nginx could use threads for file io, and linux file performance became ok as well.
As for your "performance benefit" question and nobody using it over readiness based approaches: Well yes. No idea how it compares with a traditional readiness based socket program. But it's kind of not the point either. AFAIK the scenario where POSIX AIO makes most sense is files on disk.
But as has been pointed out elsewhere, io_uring is also about making other syscalls asynchronous.