liburing icon indicating copy to clipboard operation
liburing copied to clipboard

Feature request: threading support

Open CarterLi opened this issue 5 years ago • 8 comments
trafficstars

Threading support can be very useful in async programming. For example thread joining and condvar waiting.

Futex is a good start IMO.

CarterLi avatar Dec 12 '19 03:12 CarterLi

Can you elaborate? Not quite sure what is being asked for here.

axboe avatar Dec 12 '19 04:12 axboe

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.

CarterLi avatar Dec 12 '19 04:12 CarterLi

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 avatar Jan 15 '20 13:01 CarterLi

@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:

  1. lock mutex/wait cv via io_uring, and then do something in userspace
  2. wrap an io_uring link in a critical section. E.g. [lock] -> read/etc -> ... -> [unlock]
  3. wait for multiple locks (mentioned in linked above .Net issue)
  4. something else?

isilence avatar Jan 20 '20 09:01 isilence

@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:

  1. lock mutex/wait cv via io_uring, and then do something in userspace
  2. wrap an io_uring link in a critical section. E.g. [lock] -> read/etc -> ... -> [unlock]
  3. wait for multiple locks (mentioned in linked above .Net issue)
  4. 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.

CarterLi avatar Jan 20 '20 09:01 CarterLi

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)

isilence avatar Jan 20 '20 09:01 isilence

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?

ncuwaln avatar Mar 28 '22 08:03 ncuwaln

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.

axboe avatar Mar 28 '22 12:03 axboe