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"),
|
||||
};
|
||||
|
||||
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`.
|
||||
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...)
|
||||
///
|
||||
/// Requires at least kernel v5.16.
|
||||
// TODO: can't we use slices here? and assert `Futex2.waitone_max`
|
||||
pub fn futex2_waitv(
|
||||
/// The length of `futexes` slice must not exceed `Futex2.waitone_max`
|
||||
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
|
||||
/// match of any bit. matches FUTEX_BITSET_MATCH_ANY
|
||||
pub const match_any: Bitset = @bitCast(@as(u64, 0x00000000ffffffff));
|
||||
/// Bitset must not be empty, this is only useful in test
|
||||
pub const match_any: Bitset = @bitCast(@as(u64, 0x0000_0000_ffff_ffff));
|
||||
/// 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 = .{};
|
||||
|
||||
/// Create from raw u64 value
|
||||
|
|
|
|||
|
|
@ -1806,7 +1806,6 @@ pub fn futex_wait(
|
|||
return sqe;
|
||||
}
|
||||
|
||||
// TODO: ensure flags and Wait in futexv are correct
|
||||
/// Available since kernel 6.7
|
||||
pub fn futex_waitv(
|
||||
self: *IoUring,
|
||||
|
|
@ -1821,6 +1820,55 @@ pub fn futex_waitv(
|
|||
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 {
|
||||
assert(self.fd >= 0);
|
||||
|
||||
|
|
@ -2332,7 +2380,7 @@ pub const Sqe = extern struct {
|
|||
/// msg_flags | timeout_flags | accept_flags | cancel_flags | open_flags |
|
||||
/// statx_flags | fadvise_advice | splice_flags | rename_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
|
||||
rw_flags: u32,
|
||||
/// data to be passed back at completion time
|
||||
|
|
@ -3323,6 +3371,73 @@ pub const Sqe = extern struct {
|
|||
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?
|
||||
pub fn prep_bind(
|
||||
sqe: *Sqe,
|
||||
|
|
@ -4143,6 +4258,10 @@ pub const ZcrxIfqRegister = extern struct {
|
|||
|
||||
// COMMIT: move IoUring constants to Constants
|
||||
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
|
||||
/// opcodes that instantiate a new an available direct descriptor instead
|
||||
/// of having the application pass one direct descriptor
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue