IoUringDriver
struct IoUringDriverHigh-level driver for one io_uring ring (one fd, one SQ/CQ pair, one SQE array).
Owns one IoUringRing (closes ring fd on drop) and three
mmap regions (munmap'd on drop). Exposes the
submit/reap API the upcoming UringReactor calls every
poll cycle.
Per-worker ownership: each pthread that runs a reactor loop
owns exactly one IoUringDriver. The kernel-shared rings
are SPSC per direction (kernel + this one userspace thread),
so no inter-worker synchronisation is required.
Fields:
_ring: Owning IoUringRing (substrate; provides fd +
params).
_sq_ring_ptr: Mapped SQ ring control region.
_sq_ring_len: Length of the SQ ring mapping.
_cq_ring_ptr: Mapped CQ ring control region.
_cq_ring_len: Length of the CQ ring mapping.
_sqes_ptr: Mapped SQE array.
_sqes_len: Length of the SQE array mapping.
_sq_head_ptr / _sq_tail_ptr / _sq_ring_mask / _sq_array_ptr:
Cached pointers + values into the SQ ring control
region (no per-call offset arithmetic).
_cq_head_ptr / _cq_tail_ptr / _cq_ring_mask / _cq_cqes_ptr:
Same for the CQ region.
_sq_local_tail: Userspace-side cached SQ tail; bumped
by commit_sqe, flushed to the kernel-visible
tail by submit_and_wait.
Implements Movable
__init__
def __init__(out self, entries: Int, setup_flags: UInt32 = UInt32(0), sq_thread_cpu: UInt32 = UInt32(0), sq_thread_idle: UInt32 = UInt32(0)) Set up an io_uring with entries SQEs and mmap the three required regions (SQ ring, CQ ring, SQE array).
- Args
entries: Number of SQEs (kernel rounds up to a power of two; max 32 768).setup_flags:IORING_SETUP_*flags forwarded to :class:IoUringRing. Default 0 keeps the historical interrupt-driven, unbatched behaviour. See :data:flare.runtime.io_uring_sqe.IORING_SETUP_COOP_TASKRUNetc. for the bufring path's optimal mix.sq_thread_cpu: SQPOLL CPU affinity (CPU id the kernel pins the SQPOLL thread to); ignored unlesssetup_flagsincludesIORING_SETUP_SQPOLL.sq_thread_idle: SQPOLL idle timeout in milliseconds before the kernel parks the SQPOLL thread; ignored unlesssetup_flagsincludesIORING_SETUP_SQPOLL.
Raises Error: On io_uring_setup failure or any of the
three mmap calls failing.
__deinit__
def __deinit__(deinit self) Unmap the three ring regions; the embedded IoUringRing.__deinit__ then closes the ring fd.
fd
def fd(self) -> Int Return the underlying ring fd.
sq_entries
def sq_entries(self) -> Int Return the kernel-allocated SQ size.
cq_entries
def cq_entries(self) -> Int Return the kernel-allocated CQ size.
sq_ring_mask
def sq_ring_mask(self) -> UInt32 Return the SQ ring index mask (sq_entries - 1).
cq_ring_mask
def cq_ring_mask(self) -> UInt32 Return the CQ ring index mask (cq_entries - 1).
next_sqe
def next_sqe(self) -> Pointer[UInt8, MutUntrackedOrigin] Return a writable 64-byte pointer to the next free SQE slot.
Caller fills the slot via a prep_* helper from
:mod:flare.runtime.io_uring_sqe, then calls
:meth:commit_sqe to advance the cached SQ tail.
Multiple next_sqe → commit_sqe calls may be
interleaved before submit_and_wait flushes them to
the kernel.
Returns Pointer() (NULL) if the SQ is full
(cached tail - kernel head == sq_entries).
commit_sqe
def commit_sqe(mut self) Advance the cached SQ tail by one. The kernel-visible tail is not updated until :meth:submit_and_wait is called.
Caller must have written a fully-formed SQE to the slot
returned by :meth:next_sqe before calling this.
submit_and_wait
def submit_and_wait(mut self, min_complete: Int) -> Int Flush the cached SQ tail to the kernel and call io_uring_enter.
- Args
min_complete: 0 = non-blocking submit (kernel may process SQEs but the call returns even if no CQEs are ready). Positive = block until at least this many CQEs are ready.
submit_and_wait_timeout
def submit_and_wait_timeout(mut self, min_complete: Int, timeout_ms: Int) -> Int Like :meth:submit_and_wait, but waits at most timeout_ms.
Needs IORING_ENTER_EXT_ARG (Linux 5.11+), older than every
feature the buffer-ring path already requires.
cqe_count
def cqe_count(self) -> Int Return the number of pending CQEs (kernel-visible tail - userspace head).
reap_cqe
def reap_cqe(mut self) -> Optional[IoUringCqe] Return the next pending CQE, or None if the CQ is empty.
Advances the CQ head with a release store so the kernel knows the slot is free for the next CQE.
submit_nop
def submit_nop(mut self, user_data: UInt64) -> Int Submit a single IORING_OP_NOP SQE and return the result-code from io_uring_enter.
Used by the SQ→CQ round-trip smoke test in
tests/test_io_uring_driver.mojo and as the simplest
sanity check on a fresh driver.