summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2019-06-06 10:46:13 -0600
committerJens Axboe <axboe@kernel.dk>2019-06-06 10:46:13 -0600
commit91dde5c956b1af491bc6c16ee230daa4b4b66706 (patch)
tree2d798de40c6c7a9e2ff5006ad642315e0ee8fdf1
parent9f44fb0e64e68c304d71c1cc21ddb1de7772c1c4 (diff)
Add io_uring_submit_and_wait()
Works just like io_uring_submit(), but also allows retrieving events (or waiting/polling for them) in the same call. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--src/liburing.h1
-rw-r--r--src/liburing.map1
-rw-r--r--src/queue.c32
3 files changed, 31 insertions, 3 deletions
diff --git a/src/liburing.h b/src/liburing.h
index d7aec73..1b4884a 100644
--- a/src/liburing.h
+++ b/src/liburing.h
@@ -74,6 +74,7 @@ extern int io_uring_peek_cqe(struct io_uring *ring,
extern int io_uring_wait_cqe(struct io_uring *ring,
struct io_uring_cqe **cqe_ptr);
extern int io_uring_submit(struct io_uring *ring);
+extern int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr);
extern struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring);
extern int io_uring_register_buffers(struct io_uring *ring, struct iovec *iovecs,
diff --git a/src/liburing.map b/src/liburing.map
index d940da2..302443c 100644
--- a/src/liburing.map
+++ b/src/liburing.map
@@ -6,6 +6,7 @@ LIBURING_0.1 {
io_uring_peek_cqe;
io_uring_wait_cqe;
io_uring_submit;
+ io_uring_submit_and_wait;
io_uring_get_sqe;
io_uring_register;
io_uring_setup;
diff --git a/src/queue.c b/src/queue.c
index d10fbaf..20d8910 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -78,7 +78,7 @@ static inline int sq_ring_needs_enter(struct io_uring *ring)
*
* Returns number of sqes submitted
*/
-int io_uring_submit(struct io_uring *ring)
+static int __io_uring_submit(struct io_uring *ring, unsigned wait_nr)
{
struct io_uring_sq *sq = &ring->sq;
const unsigned mask = *sq->kring_mask;
@@ -124,13 +124,19 @@ int io_uring_submit(struct io_uring *ring)
write_barrier();
}
- if (sq_ring_needs_enter(ring)) {
+ if (wait_nr || sq_ring_needs_enter(ring)) {
unsigned flags = 0;
if ((*ring->sq.kflags & IORING_SQ_NEED_WAKEUP))
flags |= IORING_ENTER_SQ_WAKEUP;
+ if (wait_nr) {
+ if (wait_nr > submitted)
+ wait_nr = submitted;
+ flags |= IORING_ENTER_GETEVENTS;
+ }
- ret = io_uring_enter(ring->ring_fd, submitted, 0, flags, NULL);
+ ret = io_uring_enter(ring->ring_fd, submitted, wait_nr, flags,
+ NULL);
if (ret < 0)
return -errno;
} else
@@ -140,6 +146,26 @@ int io_uring_submit(struct io_uring *ring)
}
/*
+ * Submit sqes acquired from io_uring_get_sqe() to the kernel.
+ *
+ * Returns number of sqes submitted
+ */
+int io_uring_submit(struct io_uring *ring)
+{
+ return __io_uring_submit(ring, 0);
+}
+
+/*
+ * Like io_uring_submit(), but allows waiting for events as well.
+ *
+ * Returns number of sqes submitted
+ */
+int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr)
+{
+ return __io_uring_submit(ring, wait_nr);
+}
+
+/*
* Return an sqe to fill. Application must later call io_uring_submit()
* when it's ready to tell the kernel about it. The caller may call this
* function multiple times before calling io_uring_submit().