What is futex support actually useful for? #986
Replies: 8 comments
-
As an application author and devout fan of liburing, I'd like to know this as well @axboe @isilence |
Beta Was this translation helpful? Give feedback.
-
io_uring encourages a ring per thread model instead of sharing b/w multiple threads, but it's absolutely fine and often inevitable to have multiple threads. And (multithreaded) apps may need mutexes and other primitives, that's where it's useful. One distinct feature is that it allows truly asynchronous mutex lock in this way. One cool example would be a coroutine suspended on a normal posix mutex or anything futex based but without actually blocking the thread. Underneath you'd issue an lock request, which is totally async and resume the coro when you get the request result back. It doesn't have to be coroutines, the app may invent async_mutex_lock() where you pass a callback or do sth else |
Beta Was this translation helpful? Give feedback.
-
Probably the primary use case is data protection. There are also msg_ring requests for communication, but often futexes make more sense and they don't require to do a syscall unless contended. |
Beta Was this translation helpful? Give feedback.
-
I've, interestingly, also written even single-threaded applications that would benefit from a concurrent mutex. The primary example is ensuring that only one instance of a computationally expensive operation is running. To this end, several tasks can be posted to the runtime but only one task is actually issuing work. |
Beta Was this translation helpful? Give feedback.
-
Pavel explained it really well already. There are also some hints in the pull request for it: |
Beta Was this translation helpful? Give feedback.
-
One of the things that is really exiting to me is that it allows you to unify waiting for IO with waiting for memory events. So if you already have a very cheap futex-based way of waiting for some event, you can now have your IO thread also be notified of that using the existing mechanism. Previously, it would require using timeouts and polling for either the futex event or new CQEs (or burn a thread to wait on the futex and tap an eventfd). Now you can wait for both with a single As for why you may want to use the futex mechanism, it supports free notification when there are no waiters, free "waiting" if the event becomes ready prior to waiting, and a cheap way to have multiple threads waiting for the same event all get woken when it occurs. These are tricky or impossible to achieve with a eventfd (assuming you need to notify multiple times). |
Beta Was this translation helpful? Give feedback.
-
Thanks for the responses, everyone. I can definitely see the use cases now. Most interestingly, I can now see how you could use async futex ops to synchronize coroutines and threads. IIUC there is no inherent reason for a futex wait to block a thread, in the same vein as send/recv. Hence, it should naturally be possible to issue multiple futex waits for different operations/coroutines regardless of the thread. I'm excited for this, as it seems to provide a very clean and uniform way to synchronize between synchronous and asynchronous code. |
Beta Was this translation helpful? Give feedback.
-
I noticed there is no Edit - Found it in manual:
|
Beta Was this translation helpful? Give feedback.
-
I see that io_uring is adding support for async futex operations and I'm curious about what the actual use cases for this are. Since io_uring encourages single-threaded use, is it possible to wait on the same futex from the same (io_uring) thread twice? Is the main use case shared memory synchronization?
Beta Was this translation helpful? Give feedback.
All reactions