落盘机制修改
This commit is contained in:
@@ -284,7 +284,16 @@ static void *worker_main(void *arg) {
|
||||
break;
|
||||
}
|
||||
|
||||
io_uring_prep_writev(sqe, t->fd, t->iovs, t->iovcnt, t->off);
|
||||
if (t->op == TASK_WRITE) {
|
||||
io_uring_prep_writev(sqe, t->fd, t->iovs, t->iovcnt, t->off);
|
||||
} else if (t->op == TASK_FSYNC) {
|
||||
io_uring_prep_fsync(sqe, t->fd, t->fsync_flags);
|
||||
} else {
|
||||
task_finish(t, -EINVAL);
|
||||
destroy_queue_push(w->parent, t);
|
||||
continue;
|
||||
}
|
||||
sqe->flags |= (unsigned char)t->sqe_flags;
|
||||
sqe->user_data = (uint64_t)(uintptr_t)t;
|
||||
prepared++;
|
||||
}
|
||||
@@ -327,8 +336,18 @@ void task_init(task_t *t) {
|
||||
if (!t) {
|
||||
return;
|
||||
}
|
||||
t->op = TASK_WRITE;
|
||||
t->fd = -1;
|
||||
t->off = 0;
|
||||
t->fsync_flags = 0;
|
||||
t->sqe_flags = 0;
|
||||
t->done = 0;
|
||||
t->res = 0;
|
||||
t->iovs = NULL;
|
||||
t->iovcnt = 0;
|
||||
t->free_iov_bases = 1;
|
||||
t->on_destroy = NULL;
|
||||
t->on_destroy_arg = NULL;
|
||||
t->next = NULL;
|
||||
}
|
||||
|
||||
@@ -355,10 +374,16 @@ void task_destroy(task_t *t) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t->on_destroy) {
|
||||
t->on_destroy(t, t->on_destroy_arg);
|
||||
}
|
||||
|
||||
if (t->iovs) {
|
||||
for (int i = 0; i < t->iovcnt; i++) {
|
||||
if (t->iovs[i].iov_base) {
|
||||
kvs_free(t->iovs[i].iov_base);
|
||||
if (t->free_iov_bases) {
|
||||
for (int i = 0; i < t->iovcnt; i++) {
|
||||
if (t->iovs[i].iov_base) {
|
||||
kvs_free(t->iovs[i].iov_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
kvs_free(t->iovs);
|
||||
@@ -678,6 +703,33 @@ static int queue_task_with_backpressure(iouring_ctx_t *ctx, task_t *t) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int queue_task_to_worker_with_backpressure(iouring_ctx_t *ctx, task_t *t, int worker_id) {
|
||||
iouring_worker_t *w;
|
||||
|
||||
if (!ctx || !ctx->workers || !t) {
|
||||
return -1;
|
||||
}
|
||||
if (worker_id < 0 || worker_id >= ctx->worker_nr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
w = &ctx->workers[worker_id];
|
||||
while (atomic_load_explicit(&ctx->stop, memory_order_acquire) == 0) {
|
||||
int need_notify = 0;
|
||||
if (spsc_try_push(&w->submit_q, t, &need_notify) == 0) {
|
||||
if (need_notify) {
|
||||
worker_notify(w);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
cleanup_finished_iouring_tasks(ctx);
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
task_t *submit_write(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int count, off_t off) {
|
||||
task_t *t;
|
||||
size_t total = 0;
|
||||
@@ -782,6 +834,92 @@ task_t *submit_write(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int
|
||||
return t;
|
||||
}
|
||||
|
||||
task_t *submit_write_ref(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int count, off_t off,
|
||||
int free_iov_bases, task_destroy_cb_t on_destroy, void *on_destroy_arg) {
|
||||
task_t *t;
|
||||
size_t total = 0;
|
||||
|
||||
if (!ctx || !ctx->workers || !bufs || !lens || count <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = (task_t *)kvs_malloc(sizeof(task_t));
|
||||
if (!t) {
|
||||
return NULL;
|
||||
}
|
||||
task_init(t);
|
||||
t->op = TASK_WRITE;
|
||||
t->fd = fd;
|
||||
t->off = off;
|
||||
t->iovcnt = count;
|
||||
t->free_iov_bases = free_iov_bases ? 1 : 0;
|
||||
t->on_destroy = on_destroy;
|
||||
t->on_destroy_arg = on_destroy_arg;
|
||||
t->iovs = (struct iovec *)kvs_malloc(sizeof(struct iovec) * (size_t)count);
|
||||
if (!t->iovs) {
|
||||
kvs_free(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!bufs[i] || lens[i] == 0) {
|
||||
task_destroy(t);
|
||||
return NULL;
|
||||
}
|
||||
if (lens[i] > SIZE_MAX - total) {
|
||||
task_destroy(t);
|
||||
return NULL;
|
||||
}
|
||||
t->iovs[i].iov_base = bufs[i];
|
||||
t->iovs[i].iov_len = lens[i];
|
||||
total += lens[i];
|
||||
}
|
||||
|
||||
if (total == 0) {
|
||||
task_destroy(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (queue_task_with_backpressure(ctx, t) != 0) {
|
||||
task_destroy(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
task_t *submit_fsync_ref(iouring_ctx_t *ctx, int fd, int worker_id, int drain,
|
||||
task_destroy_cb_t on_destroy, void *on_destroy_arg) {
|
||||
task_t *t;
|
||||
|
||||
if (!ctx || !ctx->workers || fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (worker_id < 0 || worker_id >= ctx->worker_nr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = (task_t *)kvs_malloc(sizeof(task_t));
|
||||
if (!t) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
task_init(t);
|
||||
t->op = TASK_FSYNC;
|
||||
t->fd = fd;
|
||||
t->fsync_flags = 0;
|
||||
t->sqe_flags = drain ? IOSQE_IO_DRAIN : 0;
|
||||
t->on_destroy = on_destroy;
|
||||
t->on_destroy_arg = on_destroy_arg;
|
||||
|
||||
if (queue_task_to_worker_with_backpressure(ctx, t, worker_id) != 0) {
|
||||
task_destroy(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int uring_task_complete(iouring_ctx_t *ctx) {
|
||||
if (!ctx || !ctx->workers) {
|
||||
return 1;
|
||||
|
||||
@@ -11,18 +11,26 @@
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef enum { TASK_READ, TASK_WRITE } task_op_t;
|
||||
typedef enum { TASK_READ, TASK_WRITE, TASK_FSYNC } task_op_t;
|
||||
|
||||
struct task;
|
||||
typedef void (*task_destroy_cb_t)(struct task *t, void *arg);
|
||||
|
||||
typedef struct task {
|
||||
task_op_t op;
|
||||
int fd;
|
||||
off_t off;
|
||||
unsigned fsync_flags;
|
||||
unsigned sqe_flags;
|
||||
|
||||
int res;
|
||||
_Atomic int done;
|
||||
|
||||
struct iovec *iovs;
|
||||
int iovcnt;
|
||||
int free_iov_bases;
|
||||
task_destroy_cb_t on_destroy;
|
||||
void *on_destroy_arg;
|
||||
|
||||
struct task *next;
|
||||
} task_t;
|
||||
@@ -73,6 +81,10 @@ int iouring_init(iouring_ctx_t *ctx, unsigned entries);
|
||||
void iouring_shutdown(iouring_ctx_t *ctx);
|
||||
|
||||
task_t *submit_write(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int count, off_t off);
|
||||
task_t *submit_write_ref(iouring_ctx_t *ctx, int fd, void **bufs, size_t *lens, int count, off_t off,
|
||||
int free_iov_bases, task_destroy_cb_t on_destroy, void *on_destroy_arg);
|
||||
task_t *submit_fsync_ref(iouring_ctx_t *ctx, int fd, int worker_id, int drain,
|
||||
task_destroy_cb_t on_destroy, void *on_destroy_arg);
|
||||
int uring_task_complete(iouring_ctx_t *ctx);
|
||||
void cleanup_finished_iouring_tasks(iouring_ctx_t *ctx);
|
||||
void iouring_profile_dump(iouring_ctx_t *ctx);
|
||||
|
||||
Reference in New Issue
Block a user