liburing
liburing copied to clipboard
Feature request: threading support
Threading support can be very useful in async programming. For example thread joining and condvar waiting.
Futex is a good start IMO.
Can you elaborate? Not quite sure what is being asked for here.
I mean support for futex(2).
It has nothing to do with IO, but all about asynchronous. I'm not sure that it's suit for io_uring.
Just mention: We can implement asynchronous mutex using eventfd.
struct async_mutex {
async_mutex(): efd(::eventfd(1, EFD_CLOEXEC)) {};
async_mutex(async_mutex&& other): efd(other.efd) {
other.efd = 0;
};
async_mutex(const async_mutex& other): efd(::dup(other.efd)) {};
void lock() {
eventfd_t value = 0;
auto res = eventfd_read(efd, &value);
assert(res > 0 && value == 1);
}
bool try_lock() {
eventfd_t value = 0;
auto iov = to_iov(&value, sizeof(value));
auto res = preadv2(efd, &iov, 1, 0, RWF_NOWAIT);
return res > 0;
}
task<> async_lock(io_service& service) {
eventfd_t value = 0;
int res = co_await service.read(efd, &value, sizeof(value), 0);
assert(res > 0 && value == 1);
}
void unlock() {
eventfd_write(efd, 1);
}
int efd;
};
eventfd itself can be used as a semaphore. And semaphore can be used to implement condition variable ( inefficiently )
@CarterLi, yeah... or even with read/write to a pipe. Though even with naive futex(2) support it may be hellishly slow. E.g. without context-switch-less locking from the userspace, when there is no contention.
So, I really would like to hear about your use case. There are several I have in mind:
- lock mutex/wait cv via
io_uring, and then do something in userspace - wrap an
io_uringlink in a critical section. E.g.[lock] -> read/etc -> ... -> [unlock] - wait for multiple locks (mentioned in linked above .Net issue)
- something else?
@CarterLi, yeah... or even with read/write to a pipe. Though even with naive futex(2) support it may be hellishly slow. E.g. without context-switch-less locking from the userspace, when there is no contention.
So, I really would like to hear about your use case. There are several I have in mind:
- lock mutex/wait cv via
io_uring, and then do something in userspace- wrap an
io_uringlink in a critical section. E.g.[lock] -> read/etc -> ... -> [unlock]- wait for multiple locks (mentioned in linked above .Net issue)
- something else?
Just want to implement async mutex / condvar in an efficient way, and let threading integrates with io_uring event loop better.
Here is an use case I thought before: https://github.com/CarterLi/liburing4cpp/blob/async/demo/threading.cpp
Another problem is that liburing is not thread safe ( most importantly io_uring_get_sqe ). That's another thing.
Just want to implement async mutex / condvar in an efficient way, and let threading integrates with io_uring event loop better.
Here is an use case I thought before: https://github.com/CarterLi/liburing4cpp/blob/async/demo/threading.cpp
Ok, to do that efficiently for general purpose use as your library apart from futex(2) we would need to implement userspace fast path. see pthread_mutex sources if curious.
Another problem is that liburing is not thread safe ( most importantly io_uring_get_sqe ). That's another thing.
Good point, sounds like a separate point for discussion (and a separate issue)
Another problem is that liburing is not thread safe ( most importantly io_uring_get_sqe ). That's another thing.
Good point, sounds like a separate point for discussion (and a separate issue)
Hello,Are there plans to support thread safe api for liburing?
Rings aren't meant to be shared between submitters, which is why there isn't a thread safe API for that. If you really need to do that, then I'd suggest just wrapping the submit side calls in a lock to serialize them.
And let's please keep issues on topic. This one is about futex support, not thread safe APIs.