Condy v1.9
C++ Asynchronous System Call Layer for Linux
Loading...
Searching...
No Matches
condy_uring.hpp
Go to the documentation of this file.
1
4
5#pragma once
6
7#include <liburing.h> // IWYU pragma: export
8
9#include <cerrno>
10#include <cstring>
11#include <sys/mman.h>
12
13// liburing <= 2.3 has no version macros, define them here
14
15#ifndef IO_URING_VERSION_MAJOR
16#define IO_URING_VERSION_MAJOR 2
17#endif
18
19#ifndef IO_URING_VERSION_MINOR
20#define IO_URING_VERSION_MINOR 3
21#endif
22
23#define CONDY_URING_VERSION_GE(major, minor) \
24 (IO_URING_VERSION_MAJOR > (major) || \
25 (IO_URING_VERSION_MAJOR == (major) && IO_URING_VERSION_MINOR >= (minor)))
26
27// Polyfill for io_uring_prep_uring_cmd (added in liburing 2.13)
28// Opcode exists since 2.3, only the helper function is missing
29#if !CONDY_URING_VERSION_GE(2, 13) // < 2.13
30inline void io_uring_prep_uring_cmd(struct io_uring_sqe *sqe, int cmd_op,
31 int fd) noexcept {
32 sqe->opcode = (__u8)IORING_OP_URING_CMD;
33 sqe->fd = fd;
34 sqe->cmd_op = cmd_op;
35 sqe->__pad1 = 0;
36 sqe->addr = 0ul;
37 sqe->len = 0;
38}
39#endif
40
41// Polyfill for io_uring_setup_buf_ring / io_uring_free_buf_ring
42// (added in liburing 2.4)
43#if !CONDY_URING_VERSION_GE(2, 4) // < 2.4
44inline struct io_uring_buf_ring *
45io_uring_setup_buf_ring(struct io_uring *ring, unsigned int nentries, int bgid,
46 unsigned int flags, int *err) noexcept {
47 size_t ring_size = nentries * sizeof(struct io_uring_buf);
48 auto *br = static_cast<struct io_uring_buf_ring *>(
49 mmap(nullptr, ring_size, PROT_READ | PROT_WRITE,
50 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
51 if (br == MAP_FAILED) {
52 *err = -errno;
53 return nullptr;
54 }
55
56 io_uring_buf_ring_init(br);
57
58 struct io_uring_buf_reg reg = {};
59 reg.ring_addr = reinterpret_cast<uint64_t>(br);
60 reg.ring_entries = nentries;
61 reg.bgid = bgid;
62
63 *err = 0;
64 int ret = io_uring_register_buf_ring(ring, &reg, flags);
65 if (ret != 0) {
66 munmap(br, ring_size);
67 *err = ret;
68 return nullptr;
69 }
70
71 return br;
72}
73
74inline int io_uring_free_buf_ring(struct io_uring *ring,
75 struct io_uring_buf_ring *br,
76 unsigned int nentries, int bgid) noexcept {
77 int ret = io_uring_unregister_buf_ring(ring, bgid);
78 if (ret != 0) {
79 return ret;
80 }
81 munmap(br, nentries * sizeof(struct io_uring_buf));
82 return 0;
83}
84#endif