diff options
author | David Härdeman <david@hardeman.nu> | 2020-06-12 00:52:39 +0200 |
---|---|---|
committer | David Härdeman <david@hardeman.nu> | 2020-06-12 00:52:39 +0200 |
commit | 0894b8f5c0b18b7fbbfe505bf8291495c74a3f08 (patch) | |
tree | d98b8dacaeb1cf27c9d3286d34dba2e8112e6f2b | |
parent | 20aaa834989f909841f3f96a622bb5db38fdef2d (diff) |
Improve tagged pointer handling
-rw-r--r-- | uring.c | 93 |
1 files changed, 53 insertions, 40 deletions
@@ -16,6 +16,15 @@ struct uring_ev { struct uring_task task; }; +enum cqe_type { + CQE_TYPE_NORMAL = 0x0, + CQE_TYPE_CANCEL = 0x1, + CQE_TYPE_CLOSE = 0x2, + CQE_TYPE_POLL_CANCEL = 0x3 +}; + +#define CQE_TYPE_PTR_MASK 0x3 + uint64_t sqe_count = 0; uint64_t cqe_count = 0; @@ -92,7 +101,7 @@ uring_task_destroy(struct cfg *cfg, struct uring_task *task) sqe = get_sqe(cfg, task); io_uring_prep_cancel(sqe, task, 0); - io_uring_sqe_set_data(sqe, (void *)((uintptr_t)task + 0x1)); + io_uring_sqe_set_data(sqe, (void *)((uintptr_t)task | CQE_TYPE_CANCEL)); } task->dead = true; @@ -228,9 +237,8 @@ uring_close(struct cfg *cfg, struct uring_task *task, int fd) } sqe = get_sqe(cfg, task); - task = (void *)((uintptr_t)task + 0x2); io_uring_prep_close(sqe, fd); - io_uring_sqe_set_data(sqe, task); + io_uring_sqe_set_data(sqe, (void *)((uintptr_t)task | CQE_TYPE_CLOSE)); } static void @@ -483,8 +491,7 @@ uring_poll_cancel(struct cfg *cfg, struct uring_task *task) sqe = get_sqe(cfg, task); task->dead = true; io_uring_prep_poll_remove(sqe, task); - /* FIXME: should not set this to NULL */ - io_uring_sqe_set_data(sqe, NULL); + io_uring_sqe_set_data(sqe, (void *)((uintptr_t)task | CQE_TYPE_POLL_CANCEL)); } static void @@ -530,6 +537,21 @@ uring_init(struct cfg *cfg) uev->cfg = cfg; } +static inline void +uring_print_cqe(struct cfg *cfg, const char *type, struct uring_task *task, + struct io_uring_cqe *cqe) +{ + fprintf(stderr, "uring_event_loop: got %s CQE " + "(res: %i (%s), task: %s (%p), fd: %i, cb: %p)\n", + type, + cqe->res, + cqe->res < 0 ? strerror(-cqe->res) : "ok", + task->name ? task->name : "<none>", + task, + task->fd, + task->callback); +} + void uring_event_loop(struct cfg *cfg) { @@ -551,54 +573,45 @@ uring_event_loop(struct cfg *cfg) io_uring_for_each_cqe(&cfg->uev->uring, head, cqe) { struct uring_task *task = io_uring_cqe_get_data(cqe); bool do_callback; + enum cqe_type cqe_type; cqe_count++; + cqe_type = ((uintptr_t)task & CQE_TYPE_PTR_MASK); + task = (void *)((uintptr_t)task & ~CQE_TYPE_PTR_MASK); + if (!task) die("%s: null task\n", __func__); - if (task != NULL && ((uintptr_t)task & 0x1)) { - task = (void *)((uintptr_t)task - 0x1); - fprintf(stderr, "%s: got cancellation CQE (res: %i (%s), task: %s (%p), fd: %i, cb: %p)\n", - __func__, - cqe->res, - cqe->res < 0 ? strerror(-cqe->res) : "ok", - task ? task->name : "<none>", - task, - task ? task->fd : -1, - task ? task->callback : NULL); + switch (cqe_type) { + case CQE_TYPE_CANCEL: + uring_print_cqe(cfg, "cancel", task, cqe); do_callback = false; - } else if (task != NULL && ((uintptr_t)task & 0x2)) { - task = (void *)((uintptr_t)task - 0x2); - fprintf(stderr, "%s: got close CQE (res: %i (%s), task: %s (%p), fd: %i, cb: %p)\n", - __func__, - cqe->res, - cqe->res < 0 ? strerror(-cqe->res) : "ok", - task ? task->name : "<none>", - task, - task ? task->fd : -1, - task ? task->callback : NULL); + break; + + case CQE_TYPE_CLOSE: + uring_print_cqe(cfg, "close", task, cqe); + do_callback = false; + break; + + case CQE_TYPE_POLL_CANCEL: + uring_print_cqe(cfg, "poll_cancel", task, cqe); do_callback = false; - } else { - fprintf(stderr, "%s: got CQE (res: %i (%s), task: %s (%p), fd: %i, cb: %p)\n", - __func__, - cqe->res, - cqe->res < 0 ? strerror(-cqe->res) : "ok", - task ? task->name : "<none>", - task, - task ? task->fd : -1, - task ? task->callback : NULL); + break; + + case CQE_TYPE_NORMAL: + uring_print_cqe(cfg, "standard", task, cqe); do_callback = true; - } + break; - if (!task) - error("%s: null task!?\n", __func__); + default: + die("%s: unknown CQE type\n"); + } - if (do_callback && task && task->callback) + if (do_callback && task->callback) task->callback(cfg, task, cqe->res); - if (task) - uring_task_put(cfg, task); + uring_task_put(cfg, task); if (exiting) return; |