summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2019-01-08 15:14:07 -0700
committerJens Axboe <axboe@kernel.dk>2019-01-08 15:38:01 -0700
commit6a44c6e0f7eb1d7692c96b2512974b858cfc95f0 (patch)
tree6b0bb6677f297c6d3205744eda9e0bc5139373a1
parentf93c84e1b07474a7d776403b3516feeff4f3c933 (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.c34
-rw-r--r--src/liburing.h2
-rw-r--r--src/liburing.map1
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: