26 FdTable(io_uring &ring) : ring_(ring) {}
28 FdTable(
const FdTable &) =
delete;
29 FdTable &operator=(
const FdTable &) =
delete;
30 FdTable(FdTable &&) =
delete;
31 FdTable &operator=(FdTable &&) =
delete;
39 int init(
size_t capacity) {
40 return io_uring_register_files_sparse(&ring_, capacity);
47 int destroy() {
return io_uring_unregister_files(&ring_); }
56 int update(
unsigned index_base,
const int *fds,
unsigned nr_fds) {
57 return io_uring_register_files_update(&ring_, index_base, fds, nr_fds);
70 fd_accepter_ = std::forward<Func>(accepter);
80 return io_uring_register_file_alloc_range(&ring_, offset, size);
84 std::function<void(int32_t)> fd_accepter_ =
nullptr;
99 BufferTable(io_uring &ring) : ring_(ring) {}
101 BufferTable(
const BufferTable &) =
delete;
102 BufferTable &operator=(
const BufferTable &) =
delete;
103 BufferTable(BufferTable &&) =
delete;
104 BufferTable &operator=(BufferTable &&) =
delete;
113 int r = io_uring_register_buffers_sparse(&ring_, capacity);
126 initialized_ =
false;
127 return io_uring_unregister_buffers(&ring_);
137 int update(
unsigned index_base,
const iovec *vecs,
unsigned nr_vecs) {
138 return io_uring_register_buffers_update_tag(&ring_, index_base, vecs,
142#if !IO_URING_CHECK_VERSION(2, 10)
153 unsigned int src_off = 0,
unsigned int nr = 0) {
154 auto *src_ring = &src.ring_;
155 auto *dst_ring = &ring_;
156 unsigned int flags = 0;
158 flags |= IORING_REGISTER_DST_REPLACE;
160 int r = __io_uring_clone_buffers_offset(dst_ring, src_ring, dst_off,
172 bool initialized_ =
false;
183 RingSettings(io_uring &ring) : ring_(ring) {}
187 io_uring_free_probe(probe_);
192 RingSettings(
const RingSettings &) =
delete;
193 RingSettings &operator=(
const RingSettings &) =
delete;
194 RingSettings(RingSettings &&) =
delete;
195 RingSettings &operator=(RingSettings &&) =
delete;
208 return io_uring_unregister_personality(&ring_,
id);
218 return io_uring_register_restrictions(&ring_, res, nr_res);
228 return io_uring_register_iowq_aff(&ring_, cpusz, mask);
243 return io_uring_register_iowq_max_workers(&ring_, values);
255 probe_ = io_uring_get_probe_ring(&ring_);
265#if !IO_URING_CHECK_VERSION(2, 6)
272 return io_uring_register_napi(&ring_, napi);
279 return io_uring_unregister_napi(&ring_, napi);
283#if !IO_URING_CHECK_VERSION(2, 8)
290 return io_uring_register_clock(&ring_, clock_reg);
294#if !IO_URING_CHECK_VERSION(2, 9)
301 return io_uring_resize_rings(&ring_, params);
305#if !IO_URING_CHECK_VERSION(2, 10)
312 return io_uring_set_iowait(&ring_, enable_iowait);
318 io_uring_probe *probe_ =
nullptr;
319 uint32_t features_ = 0;
327 ~Ring() { destroy(); }
329 Ring(
const Ring &) =
delete;
330 Ring &operator=(
const Ring &) =
delete;
331 Ring(Ring &&) =
delete;
332 Ring &operator=(Ring &&) =
delete;
335 int init(
unsigned int entries, io_uring_params *params,
336 [[maybe_unused]]
void *buf =
nullptr,
337 [[maybe_unused]]
size_t buf_size = 0) {
339 assert(!initialized_);
340#if !IO_URING_CHECK_VERSION(2, 5)
341 if (params->flags & IORING_SETUP_NO_MMAP) {
342 r = io_uring_queue_init_mem(entries, &ring_, params, buf, buf_size);
345 r = io_uring_queue_init_params(entries, &ring_, params);
349 settings_.features_ = params->features;
350 sqpoll_mode_ = (params->flags & IORING_SETUP_SQPOLL) != 0;
357 io_uring_queue_exit(&ring_);
358 initialized_ =
false;
362 void submit() { io_uring_submit(&ring_); }
364 template <
typename Func>
size_t reap_completions_wait(Func &&process_func) {
369 int r = io_uring_submit_and_wait(&ring_, 1);
370 if (r >= 0) [[likely]] {
372 }
else if (r == -EINTR) {
375 throw make_system_error(
"io_uring_submit_and_wait", -r);
379 io_uring_for_each_cqe(&ring_, head, cqe) {
383 io_uring_cq_advance(&ring_, reaped);
387 template <
typename Func>
size_t reap_completions(Func &&process_func) {
392 if (io_uring_peek_cqe(&ring_, &cqe) == 0) {
393 io_uring_for_each_cqe(&ring_, head, cqe) {
397 io_uring_cq_advance(&ring_, reaped);
403 void reserve_space(
size_t n) {
406 space_left = io_uring_sq_space_left(&ring_);
407 if (space_left >= n) {
414 io_uring *ring() {
return &ring_; }
416 FdTable &fd_table() {
return fd_table_; }
418 BufferTable &buffer_table() {
return buffer_table_; }
420 RingSettings &settings() {
return settings_; }
422 io_uring_sqe *get_sqe() {
423 [[maybe_unused]]
int r;
426 sqe = io_uring_get_sqe(&ring_);
430 r = io_uring_submit(&ring_);
433 r = io_uring_sqring_wait(&ring_);
441 bool initialized_ =
false;
443 bool sqpoll_mode_ =
false;
445 FdTable fd_table_{ring_};
446 BufferTable buffer_table_{ring_};
447 RingSettings settings_{ring_};
int destroy()
Destroy the buffer table.
Definition ring.hpp:125
int update(unsigned index_base, const iovec *vecs, unsigned nr_vecs)
Update the buffer table starting from the given index.
Definition ring.hpp:137
int init(size_t capacity)
Initialize the buffer table with the given capacity.
Definition ring.hpp:112
int clone_buffers(BufferTable &src, unsigned int dst_off=0, unsigned int src_off=0, unsigned int nr=0)
Clone buffers from another BufferTable into this one.
Definition ring.hpp:152
File descriptor table for io_uring.
Definition ring.hpp:24
void set_fd_accepter(Func &&accepter)
Set the accepter function for incoming file descriptors.
Definition ring.hpp:69
int update(unsigned index_base, const int *fds, unsigned nr_fds)
Update the file descriptor table starting from the given index.
Definition ring.hpp:56
int init(size_t capacity)
Initialize the file descriptor table with the given capacity.
Definition ring.hpp:39
int destroy()
Destroy the file descriptor table.
Definition ring.hpp:47
int set_file_alloc_range(unsigned offset, unsigned size)
Set the file allocation range for the fd table.
Definition ring.hpp:79
friend auto async_fixed_fd_send(FdTable &dst, int source_fd, int target_fd, unsigned int flags)
See io_uring_prep_msg_ring_fd.
Definition async_operations.hpp:898
int set_clock(io_uring_clock_register *clock_reg)
Set the clock registration for the io_uring instance.
Definition ring.hpp:289
uint32_t get_features() const
Get the supported features of the ring.
Definition ring.hpp:263
int remove_iowq_aff()
Remove I/O worker queue affinity settings.
Definition ring.hpp:234
int set_iowait(bool enable_iowait)
Enable or disable iowait for the io_uring instance.
Definition ring.hpp:311
int apply_iowq_aff(size_t cpusz, const cpu_set_t *mask)
Apply I/O worker queue affinity settings.
Definition ring.hpp:227
io_uring_probe * get_probe()
Get the io_uring probe for the ring.
Definition ring.hpp:251
int set_restrictions(io_uring_restriction *res, unsigned int nr_res)
Set restrictions for the io_uring instance.
Definition ring.hpp:217
int apply_personality()
Apply a personality to the io_uring instance.
Definition ring.hpp:202
int remove_personality(int id)
Remove a personality from the io_uring instance.
Definition ring.hpp:207
int set_iowq_max_workers(unsigned int *values)
Set the maximum number of I/O workers.
Definition ring.hpp:242
int remove_napi(io_uring_napi *napi=nullptr)
Remove NAPI settings from the io_uring instance.
Definition ring.hpp:278
int apply_napi(io_uring_napi *napi)
Apply NAPI settings to the io_uring instance.
Definition ring.hpp:271
int set_rings_size(io_uring_params *params)
Resize the rings of the io_uring instance.
Definition ring.hpp:300
The event loop runtime for executing asynchronous.
Definition runtime.hpp:76
The main namespace for the Condy library.
Definition condy.hpp:28
Internal utility classes and functions used by Condy.