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:
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user