diff options
author | Jens Axboe <axboe@kernel.dk> | 2019-01-08 15:14:07 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-01-08 15:38:01 -0700 |
commit | 6a44c6e0f7eb1d7692c96b2512974b858cfc95f0 (patch) | |
tree | 6b0bb6677f297c6d3205744eda9e0bc5139373a1 | |
parent | f93c84e1b07474a7d776403b3516feeff4f3c933 (diff) |
Add option for getting a completion without waiting
This now exposes two helpers:
io_uring_get_completion()
Return a completion, if we have one (or more) available in
the ring
io_uring_wait_completion()
Return a completion, waiting for it if necessary
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | src/io_uring.c | 34 | ||||
-rw-r--r-- | src/liburing.h | 2 | ||||
-rw-r--r-- | src/liburing.map | 1 |
3 files changed, 28 insertions, 9 deletions
diff --git a/src/io_uring.c b/src/io_uring.c index 52b3553..21ce4f9 100644 --- a/src/io_uring.c +++ b/src/io_uring.c @@ -9,39 +9,55 @@ #include "liburing.h" #include "barrier.h" -/* - * Return an IO completion, waiting for it it necessary. - */ -int io_uring_get_completion(int fd, struct io_uring_cq *cq, - struct io_uring_event **ev_ptr) +static int __io_uring_get_completion(int fd, struct io_uring_cq *cq, + struct io_uring_event **ev_ptr, int wait) { const unsigned mask = *cq->kring_mask; - struct io_uring_event *ev = NULL; unsigned head; int ret; + *ev_ptr = NULL; head = *cq->khead; do { read_barrier(); if (head != *cq->ktail) { - ev = &cq->events[head & mask]; + *ev_ptr = &cq->events[head & mask]; break; } + if (!wait) + break; ret = io_uring_enter(fd, 0, 1, IORING_ENTER_GETEVENTS); if (ret < 0) return -errno; } while (1); - if (ev) { + if (*ev_ptr) { *cq->khead = head + 1; write_barrier(); } - *ev_ptr = ev; return 0; } /* + * Return an IO completion, if one is readily available + */ +int io_uring_get_completion(int fd, struct io_uring_cq *cq, + struct io_uring_event **ev_ptr) +{ + return __io_uring_get_completion(fd, cq, ev_ptr, 0); +} + +/* + * Return an IO completion, waiting for it if necessary + */ +int io_uring_wait_completion(int fd, struct io_uring_cq *cq, + struct io_uring_event **ev_ptr) +{ + return __io_uring_get_completion(fd, cq, ev_ptr, 1); +} + +/* * Submit iocbs acquired from io_uring_get_iocb() to the kernel. * * Returns number of iocbs submitted diff --git a/src/liburing.h b/src/liburing.h index 454591a..8c81978 100644 --- a/src/liburing.h +++ b/src/liburing.h @@ -51,6 +51,8 @@ extern void io_uring_queue_exit(int fd, struct io_uring_sq *sq, struct io_uring_cq *cq); extern int io_uring_get_completion(int fd, struct io_uring_cq *cq, struct io_uring_event **ev_ptr); +extern int io_uring_wait_completion(int fd, struct io_uring_cq *cq, + struct io_uring_event **ev_ptr); extern int io_uring_submit(int fd, struct io_uring_sq *sq); extern struct io_uring_iocb *io_uring_get_iocb(struct io_uring_sq *sq); diff --git a/src/liburing.map b/src/liburing.map index ef48835..85e78ca 100644 --- a/src/liburing.map +++ b/src/liburing.map @@ -3,6 +3,7 @@ LIBURING_0.1 { io_uring_queue_init; io_uring_queue_exit; io_uring_get_completion; + io_uring_wait_completion; io_uring_submit; io_uring_get_iocb; local: |