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>
This commit is contained in:
Jens Axboe
2019-01-08 15:14:07 -07:00
parent f93c84e1b0
commit 6a44c6e0f7
3 changed files with 28 additions and 9 deletions

View File

@@ -9,38 +9,54 @@
#include "liburing.h" #include "liburing.h"
#include "barrier.h" #include "barrier.h"
/* static int __io_uring_get_completion(int fd, struct io_uring_cq *cq,
* Return an IO completion, waiting for it it necessary. struct io_uring_event **ev_ptr, int wait)
*/
int io_uring_get_completion(int fd, struct io_uring_cq *cq,
struct io_uring_event **ev_ptr)
{ {
const unsigned mask = *cq->kring_mask; const unsigned mask = *cq->kring_mask;
struct io_uring_event *ev = NULL;
unsigned head; unsigned head;
int ret; int ret;
*ev_ptr = NULL;
head = *cq->khead; head = *cq->khead;
do { do {
read_barrier(); read_barrier();
if (head != *cq->ktail) { if (head != *cq->ktail) {
ev = &cq->events[head & mask]; *ev_ptr = &cq->events[head & mask];
break; break;
} }
if (!wait)
break;
ret = io_uring_enter(fd, 0, 1, IORING_ENTER_GETEVENTS); ret = io_uring_enter(fd, 0, 1, IORING_ENTER_GETEVENTS);
if (ret < 0) if (ret < 0)
return -errno; return -errno;
} while (1); } while (1);
if (ev) { if (*ev_ptr) {
*cq->khead = head + 1; *cq->khead = head + 1;
write_barrier(); write_barrier();
} }
*ev_ptr = ev;
return 0; 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. * Submit iocbs acquired from io_uring_get_iocb() to the kernel.
* *

View File

@@ -51,6 +51,8 @@ extern void io_uring_queue_exit(int fd, struct io_uring_sq *sq,
struct io_uring_cq *cq); struct io_uring_cq *cq);
extern int io_uring_get_completion(int fd, struct io_uring_cq *cq, extern int io_uring_get_completion(int fd, struct io_uring_cq *cq,
struct io_uring_event **ev_ptr); 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 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); extern struct io_uring_iocb *io_uring_get_iocb(struct io_uring_sq *sq);

View File

@@ -3,6 +3,7 @@ LIBURING_0.1 {
io_uring_queue_init; io_uring_queue_init;
io_uring_queue_exit; io_uring_queue_exit;
io_uring_get_completion; io_uring_get_completion;
io_uring_wait_completion;
io_uring_submit; io_uring_submit;
io_uring_get_iocb; io_uring_get_iocb;
local: local: