mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
IoUring: Implement set_iowait functionality
closes https://github.com/ziglang/zig/issues/25566 closes https://github.com/ziglang/zig/pull/25604 and IoUring enter_flags() helper function add typed Init flags which match int_flags in liburing Co-authored-by: RaidoAun <45874591+RaidoAun@users.noreply.github.com> Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
parent
5b49e7af9e
commit
8a9320c013
1 changed files with 57 additions and 6 deletions
|
|
@ -16,6 +16,8 @@ sq: Sq,
|
||||||
cq: Cq,
|
cq: Cq,
|
||||||
flags: uflags.Setup,
|
flags: uflags.Setup,
|
||||||
features: uflags.Features,
|
features: uflags.Features,
|
||||||
|
/// matches int_flags in liburing
|
||||||
|
init_flags: uflags.Init,
|
||||||
|
|
||||||
/// A friendly way to setup an io_uring, with default linux.io_uring_params.
|
/// A friendly way to setup an io_uring, with default linux.io_uring_params.
|
||||||
/// `entries` must be a power of two between 1 and 32768, although the kernel
|
/// `entries` must be a power of two between 1 and 32768, although the kernel
|
||||||
|
|
@ -131,6 +133,7 @@ pub fn init_params(entries: u16, p: *Params) !IoUring {
|
||||||
.cq = cq,
|
.cq = cq,
|
||||||
.flags = p.flags,
|
.flags = p.flags,
|
||||||
.features = p.features,
|
.features = p.features,
|
||||||
|
.init_flags = .{},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +185,7 @@ pub fn submit(self: *IoUring) !u32 {
|
||||||
/// Matches the implementation of `io_uring_submit_and_wait()` in liburing.
|
/// Matches the implementation of `io_uring_submit_and_wait()` in liburing.
|
||||||
pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
|
pub fn submit_and_wait(self: *IoUring, wait_nr: u32) !u32 {
|
||||||
const submitted = self.flush_sq();
|
const submitted = self.flush_sq();
|
||||||
var flags: uflags.Enter = .{};
|
var flags: uflags.Enter = self.enter_flags();
|
||||||
if (self.sq_ring_needs_enter(&flags) or wait_nr > 0) {
|
if (self.sq_ring_needs_enter(&flags) or wait_nr > 0) {
|
||||||
if (wait_nr > 0 or self.flags.iopoll) {
|
if (wait_nr > 0 or self.flags.iopoll) {
|
||||||
flags.getevents = true;
|
flags.getevents = true;
|
||||||
|
|
@ -264,7 +267,7 @@ pub fn flush_sq(self: *IoUring) u32 {
|
||||||
/// awakened. For the latter case, we set the SQ thread wakeup flag.
|
/// awakened. For the latter case, we set the SQ thread wakeup flag.
|
||||||
/// Matches the implementation of `sq_ring_needs_enter()` in liburing.
|
/// Matches the implementation of `sq_ring_needs_enter()` in liburing.
|
||||||
pub fn sq_ring_needs_enter(self: *IoUring, flags: *uflags.Enter) bool {
|
pub fn sq_ring_needs_enter(self: *IoUring, flags: *uflags.Enter) bool {
|
||||||
assert(flags.*.empty());
|
assert(flags.*.valid_init_flags());
|
||||||
if (!self.flags.sqpoll) return true;
|
if (!self.flags.sqpoll) return true;
|
||||||
if (@atomicLoad(Sq.Flags, self.sq.flags, .unordered).need_wakeup) {
|
if (@atomicLoad(Sq.Flags, self.sq.flags, .unordered).need_wakeup) {
|
||||||
flags.*.sq_wakeup = true;
|
flags.*.sq_wakeup = true;
|
||||||
|
|
@ -309,7 +312,12 @@ pub fn copy_cqes(self: *IoUring, cqes: []Cqe, wait_nr: u32) !u32 {
|
||||||
const count = self.copy_cqes_ready(cqes);
|
const count = self.copy_cqes_ready(cqes);
|
||||||
if (count > 0) return count;
|
if (count > 0) return count;
|
||||||
if (self.cq_ring_needs_flush() or wait_nr > 0) {
|
if (self.cq_ring_needs_flush() or wait_nr > 0) {
|
||||||
_ = try self.enter(0, wait_nr, .{ .getevents = true });
|
const flags = blk: {
|
||||||
|
var flags = self.enter_flags();
|
||||||
|
flags.getevents = true;
|
||||||
|
break :blk flags;
|
||||||
|
};
|
||||||
|
_ = try self.enter(0, wait_nr, flags);
|
||||||
return self.copy_cqes_ready(cqes);
|
return self.copy_cqes_ready(cqes);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -374,6 +382,20 @@ pub fn cq_advance(self: *IoUring, count: u32) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enable/disable setting of iowait by the kernel.
|
||||||
|
/// matches `io_uring_set_iowait` in liburing
|
||||||
|
pub fn set_iowait(self: *IoUring, enable_iowait: bool) !void {
|
||||||
|
if (!self.features.no_iowait) {
|
||||||
|
return error.SystemOutdated;
|
||||||
|
}
|
||||||
|
self.init_flags.no_iowait = !enable_iowait;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// matches `ring_enter_flags()` in liburing
|
||||||
|
pub fn enter_flags(self: *IoUring) uflags.Enter {
|
||||||
|
return self.init_flags.enter_flags();
|
||||||
|
}
|
||||||
|
|
||||||
/// Queues (but does not submit) an SQE to perform a `splice(2)`
|
/// Queues (but does not submit) an SQE to perform a `splice(2)`
|
||||||
/// Either `fd_in` or `fd_out` must be a pipe.
|
/// Either `fd_in` or `fd_out` must be a pipe.
|
||||||
/// If `fd_in` refers to a pipe, `off_in` is ignored and must be set to
|
/// If `fd_in` refers to a pipe, `off_in` is ignored and must be set to
|
||||||
|
|
@ -4190,13 +4212,41 @@ pub const uflags = struct {
|
||||||
no_iowait: bool = false,
|
no_iowait: bool = false,
|
||||||
_9: u24 = 0,
|
_9: u24 = 0,
|
||||||
|
|
||||||
pub fn empty(enter_flags: Enter) bool {
|
/// Ensure only `Init` flags usable in `Enter` are set
|
||||||
return @as(u32, @bitCast(enter_flags)) == 0;
|
pub fn valid_init_flags(self: Enter) bool {
|
||||||
|
const valid_flags: u32 = @bitCast(Enter{ .registered_ring = true, .no_iowait = true });
|
||||||
|
const flags: u32 = @bitCast(self);
|
||||||
|
// check if any invalid flags are set
|
||||||
|
return (flags & ~valid_flags) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty(flags: Enter) bool {
|
||||||
|
return @as(u32, @bitCast(flags)) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// matches INT_FLAG_* in liburing
|
||||||
|
pub const Init = packed struct(u8) {
|
||||||
|
reg_reg_ring: bool = false,
|
||||||
|
app_mem: bool = false,
|
||||||
|
cq_enter: bool = false,
|
||||||
|
_4: u1 = 0,
|
||||||
|
/// matches `registered_ring` flag in `Enter`
|
||||||
|
reg_ring: bool = false,
|
||||||
|
_6: u2 = 0,
|
||||||
|
/// matches `no_iowait` flag in `Enter`
|
||||||
|
no_iowait: bool = false,
|
||||||
|
|
||||||
|
/// Return all valid `Enter` flags set in `Init`
|
||||||
|
pub fn enter_flags(self: Init) Enter {
|
||||||
|
const valid_flags: u8 = @bitCast(Init{ .reg_ring = true, .no_iowait = true });
|
||||||
|
const flags: u8 = @bitCast(self);
|
||||||
|
return @bitCast(@as(u32, @intCast(flags & valid_flags)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// io_uring_params.features flags
|
/// io_uring_params.features flags
|
||||||
const Features = packed struct(u32) {
|
pub const Features = packed struct(u32) {
|
||||||
single_mmap: bool = false,
|
single_mmap: bool = false,
|
||||||
nodrop: bool = false,
|
nodrop: bool = false,
|
||||||
submit_stable: bool = false,
|
submit_stable: bool = false,
|
||||||
|
|
@ -4223,6 +4273,7 @@ pub const uflags = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `io_uring_register(2)` opcodes and arguments
|
/// `io_uring_register(2)` opcodes and arguments
|
||||||
/// matches `io_uring_register_op` in liburing
|
/// matches `io_uring_register_op` in liburing
|
||||||
pub const RegisterOp = enum(u8) {
|
pub const RegisterOp = enum(u8) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue