mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
IoUring: Working on Pipe2 flags
Build on the extensive work already done IoUring: add fixed_fd_install, ftruncate, cmd_discard Working on IoUring pipe flags Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
parent
be63611c64
commit
ac53361721
2 changed files with 281 additions and 5 deletions
|
|
@ -494,6 +494,161 @@ pub const O = switch (native_arch) {
|
||||||
else => @compileError("missing std.os.linux.O constants for this architecture"),
|
else => @compileError("missing std.os.linux.O constants for this architecture"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Pipe2 = switch (native_arch) {
|
||||||
|
.x86_64, .x86, .riscv32, .riscv64, .loongarch64 => packed struct(u32) {
|
||||||
|
_: u7 = 0,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
_9: u3 = 0,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
_13: u2 = 0,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
_16: u4 = 0,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
_21: u12 = 0,
|
||||||
|
},
|
||||||
|
.aarch64, .aarch64_be, .arm, .armeb, .thumb, .thumbeb => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u4 = 0,
|
||||||
|
CREAT: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
APPEND: bool = false,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
DSYNC: bool = false,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
LARGEFILE: bool = false,
|
||||||
|
NOATIME: bool = false,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
SYNC: bool = false,
|
||||||
|
PATH: bool = false,
|
||||||
|
TMPFILE: bool = false,
|
||||||
|
_23: u9 = 0,
|
||||||
|
},
|
||||||
|
.sparc64 => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u1 = 0,
|
||||||
|
APPEND: bool = false,
|
||||||
|
_4: u2 = 0,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
_7: u2 = 0,
|
||||||
|
CREAT: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
_12: u1 = 0,
|
||||||
|
DSYNC: bool = false,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
_18: u2 = 0,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
NOATIME: bool = false,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
SYNC: bool = false,
|
||||||
|
PATH: bool = false,
|
||||||
|
TMPFILE: bool = false,
|
||||||
|
_27: u6 = 0,
|
||||||
|
},
|
||||||
|
.mips, .mipsel, .mips64, .mips64el => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u1 = 0,
|
||||||
|
APPEND: bool = false,
|
||||||
|
DSYNC: bool = false,
|
||||||
|
_5: u2 = 0,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
CREAT: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
LARGEFILE: bool = false,
|
||||||
|
SYNC: bool = false,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
NOATIME: bool = false, //
|
||||||
|
CLOEXEC: bool = false,
|
||||||
|
_20: u1 = 0,
|
||||||
|
PATH: bool = false,
|
||||||
|
TMPFILE: bool = false,
|
||||||
|
_23: u9 = 0,
|
||||||
|
},
|
||||||
|
.powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u4 = 0,
|
||||||
|
CREAT: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
APPEND: bool = false,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
DSYNC: bool = false,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
LARGEFILE: bool = false,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
NOATIME: bool = false,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
SYNC: bool = false,
|
||||||
|
PATH: bool = false,
|
||||||
|
TMPFILE: bool = false,
|
||||||
|
_23: u9 = 0,
|
||||||
|
},
|
||||||
|
.hexagon, .or1k, .s390x => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u4 = 0,
|
||||||
|
CREAT: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
APPEND: bool = false,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
DSYNC: bool = false,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
LARGEFILE: bool = false,
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
NOATIME: bool = false,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
_20: u1 = 0,
|
||||||
|
PATH: bool = false,
|
||||||
|
_22: u10 = 0,
|
||||||
|
|
||||||
|
// #define O_RSYNC 04010000
|
||||||
|
// #define O_SYNC 04010000
|
||||||
|
// #define O_TMPFILE 020200000
|
||||||
|
// #define O_NDELAY O_NONBLOCK
|
||||||
|
},
|
||||||
|
.m68k => packed struct(u32) {
|
||||||
|
ACCMODE: ACCMODE = .RDONLY,
|
||||||
|
_2: u4 = 0,
|
||||||
|
CREAT: bool = false,
|
||||||
|
EXCL: bool = false, //
|
||||||
|
NOCTTY: bool = false,
|
||||||
|
TRUNC: bool = false,
|
||||||
|
APPEND: bool = false,
|
||||||
|
NONBLOCK: bool = false, //
|
||||||
|
DSYNC: bool = false,
|
||||||
|
ASYNC: bool = false,
|
||||||
|
DIRECTORY: bool = false,
|
||||||
|
NOFOLLOW: bool = false,
|
||||||
|
DIRECT: bool = false, //
|
||||||
|
LARGEFILE: bool = false,
|
||||||
|
NOATIME: bool = false,
|
||||||
|
CLOEXEC: bool = false, //
|
||||||
|
_20: u1 = 0,
|
||||||
|
PATH: bool = false,
|
||||||
|
_22: u10 = 0,
|
||||||
|
},
|
||||||
|
else => @compileError("missing std.os.linux.O constants for this architecture"),
|
||||||
|
};
|
||||||
|
|
||||||
/// Set by startup code, used by `getauxval`.
|
/// Set by startup code, used by `getauxval`.
|
||||||
pub var elf_aux_maybe: ?[*]std.elf.Auxv = null;
|
pub var elf_aux_maybe: ?[*]std.elf.Auxv = null;
|
||||||
|
|
||||||
|
|
@ -745,7 +900,6 @@ pub fn futex_4arg(uaddr: *const u32, futex_op: FUTEX_OP, val: u32, timeout: ?*co
|
||||||
/// most recently woken, nor...)
|
/// most recently woken, nor...)
|
||||||
///
|
///
|
||||||
/// Requires at least kernel v5.16.
|
/// Requires at least kernel v5.16.
|
||||||
// TODO: can't we use slices here? and assert `Futex2.waitone_max`
|
|
||||||
pub fn futex2_waitv(
|
pub fn futex2_waitv(
|
||||||
/// The length of `futexes` slice must not exceed `Futex2.waitone_max`
|
/// The length of `futexes` slice must not exceed `Futex2.waitone_max`
|
||||||
futexes: []const Futex2.WaitOne,
|
futexes: []const Futex2.WaitOne,
|
||||||
|
|
@ -3757,8 +3911,11 @@ pub const Futex2 = struct {
|
||||||
|
|
||||||
/// `Bitset` with all bits set for the FUTEX_xxx_BITSET OPs to request a
|
/// `Bitset` with all bits set for the FUTEX_xxx_BITSET OPs to request a
|
||||||
/// match of any bit. matches FUTEX_BITSET_MATCH_ANY
|
/// match of any bit. matches FUTEX_BITSET_MATCH_ANY
|
||||||
pub const match_any: Bitset = @bitCast(@as(u64, 0x00000000ffffffff));
|
pub const match_any: Bitset = @bitCast(@as(u64, 0x0000_0000_ffff_ffff));
|
||||||
/// Bitset must not be empty, this is only useful in test
|
/// An empty `Bitset` will not wake any threads because the kernel
|
||||||
|
/// requires at least one bit to be set in the bitmask to identify
|
||||||
|
/// which waiters should be woken up. Therefore, no action will be
|
||||||
|
/// taken if the bitset is zero, this is only useful in test
|
||||||
pub const empty: Bitset = .{};
|
pub const empty: Bitset = .{};
|
||||||
|
|
||||||
/// Create from raw u64 value
|
/// Create from raw u64 value
|
||||||
|
|
|
||||||
|
|
@ -1806,7 +1806,6 @@ pub fn futex_wait(
|
||||||
return sqe;
|
return sqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ensure flags and Wait in futexv are correct
|
|
||||||
/// Available since kernel 6.7
|
/// Available since kernel 6.7
|
||||||
pub fn futex_waitv(
|
pub fn futex_waitv(
|
||||||
self: *IoUring,
|
self: *IoUring,
|
||||||
|
|
@ -1821,6 +1820,55 @@ pub fn futex_waitv(
|
||||||
return sqe;
|
return sqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fixed_fd_install(
|
||||||
|
self: *IoUring,
|
||||||
|
user_data: u64,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
flags: uflags.FixedFd,
|
||||||
|
) !*Sqe {
|
||||||
|
const sqe = try self.get_sqe();
|
||||||
|
sqe.prep_fixed_fd_install(fd, flags);
|
||||||
|
sqe.user_data = user_data;
|
||||||
|
return sqe;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ftruncate(
|
||||||
|
self: *IoUring,
|
||||||
|
user_data: u64,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
offset: u64,
|
||||||
|
) !*Sqe {
|
||||||
|
const sqe = try self.get_sqe();
|
||||||
|
sqe.prep_ftruncate(fd, offset);
|
||||||
|
sqe.user_data = user_data;
|
||||||
|
return sqe;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cmd_discard(
|
||||||
|
self: *IoUring,
|
||||||
|
user_data: u64,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
offset: u64,
|
||||||
|
nbytes: u64,
|
||||||
|
) !*Sqe {
|
||||||
|
const sqe = try self.get_sqe();
|
||||||
|
sqe.prep_cmd_discard(fd, offset, nbytes);
|
||||||
|
sqe.user_data = user_data;
|
||||||
|
return sqe;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pipe(
|
||||||
|
self: *IoUring,
|
||||||
|
user_data: u64,
|
||||||
|
fds: *[2]linux.fd_t,
|
||||||
|
flags: uflags.,
|
||||||
|
) !*Sqe {
|
||||||
|
const sqe = try self.get_sqe();
|
||||||
|
sqe.prep_pipe(fds, offset, nbytes);
|
||||||
|
sqe.user_data = user_data;
|
||||||
|
return sqe;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register_buffers_sparse(self: *IoUring, nr: u32) !void {
|
pub fn register_buffers_sparse(self: *IoUring, nr: u32) !void {
|
||||||
assert(self.fd >= 0);
|
assert(self.fd >= 0);
|
||||||
|
|
||||||
|
|
@ -2332,7 +2380,7 @@ pub const Sqe = extern struct {
|
||||||
/// msg_flags | timeout_flags | accept_flags | cancel_flags | open_flags |
|
/// msg_flags | timeout_flags | accept_flags | cancel_flags | open_flags |
|
||||||
/// statx_flags | fadvise_advice | splice_flags | rename_flags |
|
/// statx_flags | fadvise_advice | splice_flags | rename_flags |
|
||||||
/// unlink_flags | hardlink_flags xattr_flags | msg_ring_flags |
|
/// unlink_flags | hardlink_flags xattr_flags | msg_ring_flags |
|
||||||
/// uring_cmd_flags | waitid_flags | futex_flags install_fd_flags |
|
/// uring_cmd_flags | waitid_flags | futex_flags | install_fd_flags |
|
||||||
/// nop_flags | pipe_flags
|
/// nop_flags | pipe_flags
|
||||||
rw_flags: u32,
|
rw_flags: u32,
|
||||||
/// data to be passed back at completion time
|
/// data to be passed back at completion time
|
||||||
|
|
@ -3323,6 +3371,73 @@ pub const Sqe = extern struct {
|
||||||
sqe.rw_flags = flags;
|
sqe.rw_flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prep_fixed_fd_install(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
flags: uflags.FixedFd,
|
||||||
|
) void {
|
||||||
|
sqe.prep_rw(
|
||||||
|
.fixed_fd_install,
|
||||||
|
fd,
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
sqe.flags = .{ .fixed_file = true };
|
||||||
|
sqe.rw_flags = @bitCast(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prep_ftruncate(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
offset: u64,
|
||||||
|
) void {
|
||||||
|
sqe.prep_rw(
|
||||||
|
.ftruncate,
|
||||||
|
fd,
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prep_cmd_discard(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
offset: u64,
|
||||||
|
nbytes: u64,
|
||||||
|
) void {
|
||||||
|
sqe.prep_rw(
|
||||||
|
.uring_cmd,
|
||||||
|
fd,
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
// sqe.off maps to sqe.cmd_op in liburing
|
||||||
|
sqe.off = constants.BLOCK_URING_CMD_DISCARD;
|
||||||
|
sqe.addr = offset;
|
||||||
|
sqe.addr3 = nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prep_pipe(
|
||||||
|
sqe: *Sqe,
|
||||||
|
fd: linux.fd_t,
|
||||||
|
offset: u64,
|
||||||
|
nbytes: u64,
|
||||||
|
) void {
|
||||||
|
sqe.prep_rw(
|
||||||
|
.uring_cmd,
|
||||||
|
fd,
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
// sqe.off maps to sqe.cmd_op in liburing
|
||||||
|
sqe.off = constants.BLOCK_URING_CMD_DISCARD;
|
||||||
|
sqe.addr = offset;
|
||||||
|
sqe.addr3 = nbytes;
|
||||||
|
}
|
||||||
// TODO: maybe remove unused flag fields?
|
// TODO: maybe remove unused flag fields?
|
||||||
pub fn prep_bind(
|
pub fn prep_bind(
|
||||||
sqe: *Sqe,
|
sqe: *Sqe,
|
||||||
|
|
@ -4143,6 +4258,10 @@ pub const ZcrxIfqRegister = extern struct {
|
||||||
|
|
||||||
// COMMIT: move IoUring constants to Constants
|
// COMMIT: move IoUring constants to Constants
|
||||||
pub const constants = struct {
|
pub const constants = struct {
|
||||||
|
/// io_uring block file commands, see IORING_OP_URING_CMD.
|
||||||
|
/// It's a different number space from ioctl(), reuse the block's code 0x12.
|
||||||
|
/// It is the value of ioctl.IO(0x12, 0) at runtime
|
||||||
|
pub const BLOCK_URING_CMD_DISCARD = 0x1200;
|
||||||
/// If sqe.file_index (splice_fd_in in Zig Struct) is set to this for
|
/// If sqe.file_index (splice_fd_in in Zig Struct) is set to this for
|
||||||
/// opcodes that instantiate a new an available direct descriptor instead
|
/// opcodes that instantiate a new an available direct descriptor instead
|
||||||
/// of having the application pass one direct descriptor
|
/// of having the application pass one direct descriptor
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue