mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
IoUring: Fix merge conflicts
use flags in Threaded change futex signature to expect *const atomic.Value(u32) fix IoUring timeout test Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
parent
0db6c947c5
commit
62fb6db2cd
7 changed files with 74 additions and 58 deletions
|
|
@ -1289,8 +1289,7 @@ fn dirStatPathLinux(
|
|||
var path_buffer: [posix.PATH_MAX]u8 = undefined;
|
||||
const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
|
||||
|
||||
const flags: u32 = linux.AT.NO_AUTOMOUNT |
|
||||
@as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);
|
||||
const flags: linux.At = .{ .no_automount = true, .symlink_nofollow = if (!options.follow_symlinks) true else false };
|
||||
|
||||
while (true) {
|
||||
try t.checkCancel();
|
||||
|
|
@ -1299,7 +1298,15 @@ fn dirStatPathLinux(
|
|||
dir.handle,
|
||||
sub_path_posix,
|
||||
flags,
|
||||
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
|
||||
.{
|
||||
.ino = true,
|
||||
.size = true,
|
||||
.type = true,
|
||||
.mode = true,
|
||||
.atime = true,
|
||||
.mtime = true,
|
||||
.ctime = true,
|
||||
},
|
||||
&statx,
|
||||
);
|
||||
switch (linux.errno(rc)) {
|
||||
|
|
@ -1445,8 +1452,16 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
|
|||
const rc = linux.statx(
|
||||
file.handle,
|
||||
"",
|
||||
linux.AT.EMPTY_PATH,
|
||||
linux.STATX_INO | linux.STATX_SIZE | linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_ATIME | linux.STATX_MTIME | linux.STATX_CTIME,
|
||||
.{ .empty_path = true },
|
||||
.{
|
||||
.ino = true,
|
||||
.size = true,
|
||||
.type = true,
|
||||
.mode = true,
|
||||
.atime = true,
|
||||
.mtime = true,
|
||||
.ctime = true,
|
||||
},
|
||||
&statx,
|
||||
);
|
||||
switch (linux.errno(rc)) {
|
||||
|
|
@ -5862,7 +5877,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
|
|||
.linux => {
|
||||
const linux = std.os.linux;
|
||||
switch (linux.errno(linux.futex_3arg(
|
||||
&ptr.raw,
|
||||
ptr,
|
||||
.{ .cmd = .WAKE, .private = true },
|
||||
@min(max_waiters, std.math.maxInt(i32)),
|
||||
))) {
|
||||
|
|
|
|||
|
|
@ -1216,8 +1216,8 @@ const LinuxThreadImpl = struct {
|
|||
thread: *ThreadCompletion,
|
||||
|
||||
const ThreadCompletion = struct {
|
||||
completion: Completion = Completion.init(.running),
|
||||
child_tid: std.atomic.Value(i32) = std.atomic.Value(i32).init(1),
|
||||
completion: Completion = .init(.running),
|
||||
child_tid: std.atomic.Value(i32) = .init(1),
|
||||
parent_tid: i32 = undefined,
|
||||
mapped: []align(std.heap.page_size_min) u8,
|
||||
|
||||
|
|
@ -1662,7 +1662,7 @@ const LinuxThreadImpl = struct {
|
|||
if (tid == 0) break;
|
||||
|
||||
switch (linux.errno(linux.futex_4arg(
|
||||
@ptrCast(&self.thread.child_tid.raw),
|
||||
@ptrCast(&self.thread.child_tid),
|
||||
.{ .cmd = .WAIT, .private = false },
|
||||
@bitCast(tid),
|
||||
null,
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ const LinuxImpl = struct {
|
|||
}
|
||||
|
||||
const rc = linux.futex_4arg(
|
||||
&ptr.raw,
|
||||
ptr,
|
||||
.{ .cmd = .WAIT, .private = true },
|
||||
expect,
|
||||
if (timeout != null) &ts else null,
|
||||
|
|
@ -285,7 +285,7 @@ const LinuxImpl = struct {
|
|||
|
||||
fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
|
||||
const rc = linux.futex_3arg(
|
||||
&ptr.raw,
|
||||
ptr,
|
||||
.{ .cmd = .WAKE, .private = true },
|
||||
@min(max_waiters, std.math.maxInt(i32)),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//! * Implement all the syscalls in the same way that libc functions will
|
||||
//! provide `rename` when only the `renameat` syscall exists.
|
||||
const std = @import("../std.zig");
|
||||
const atomic = std.atomic;
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const maxInt = std.math.maxInt;
|
||||
|
|
@ -754,7 +755,7 @@ pub const futex_param4 = extern union {
|
|||
/// The futex_op parameter is a sub-command and flags. The sub-command
|
||||
/// defines which of the subsequent paramters are relevant.
|
||||
pub fn futex(
|
||||
uaddr: *const u32,
|
||||
uaddr: *const atomic.Value(u32),
|
||||
futex_op: FUTEX_OP,
|
||||
val: u32,
|
||||
val2timeout: futex_param4,
|
||||
|
|
@ -774,7 +775,7 @@ pub fn futex(
|
|||
|
||||
/// Three-argument variation of the v1 futex call. Only suitable for a
|
||||
/// futex_op that ignores the remaining arguments (e.g., FUTUX_OP.WAKE).
|
||||
pub fn futex_3arg(uaddr: *const u32, futex_op: FUTEX_OP, val: u32) usize {
|
||||
pub fn futex_3arg(uaddr: *const atomic.Value(u32), futex_op: FUTEX_OP, val: u32) usize {
|
||||
return syscall3(
|
||||
if (@hasField(SYS, "futex") and native_arch != .hexagon) .futex else .futex_time64,
|
||||
@intFromPtr(uaddr),
|
||||
|
|
@ -785,7 +786,7 @@ pub fn futex_3arg(uaddr: *const u32, futex_op: FUTEX_OP, val: u32) usize {
|
|||
|
||||
/// Four-argument variation on the v1 futex call. Only suitable for
|
||||
/// futex_op that ignores the remaining arguments (e.g., FUTEX_OP.WAIT).
|
||||
pub fn futex_4arg(uaddr: *const u32, futex_op: FUTEX_OP, val: u32, timeout: ?*const timespec) usize {
|
||||
pub fn futex_4arg(uaddr: *const atomic.Value(u32), futex_op: FUTEX_OP, val: u32, timeout: ?*const timespec) usize {
|
||||
return syscall4(
|
||||
if (@hasField(SYS, "futex") and native_arch != .hexagon) .futex else .futex_time64,
|
||||
@intFromPtr(uaddr),
|
||||
|
|
@ -838,7 +839,7 @@ pub fn futex2_waitv(
|
|||
/// Requires at least kernel v6.7.
|
||||
pub fn futex2_wait(
|
||||
/// Address of the futex to wait on.
|
||||
uaddr: *const u32,
|
||||
uaddr: *const atomic.Value(u32),
|
||||
/// Value of `uaddr`.
|
||||
val: usize,
|
||||
/// Bitmask to match against incoming wakeup masks. Must not be zero.
|
||||
|
|
@ -867,7 +868,7 @@ pub fn futex2_wait(
|
|||
/// Requires at least kernel v6.7.
|
||||
pub fn futex2_wake(
|
||||
/// Futex to wake
|
||||
uaddr: *const u32,
|
||||
uaddr: *const atomic.Value(u32),
|
||||
/// Bitmask to match against waiters.
|
||||
mask: Futex2.Bitset,
|
||||
/// Maximum number of waiters on the futex to wake.
|
||||
|
|
|
|||
|
|
@ -1694,7 +1694,7 @@ pub fn socket(
|
|||
domain: linux.Af,
|
||||
socket_type: linux.Sock,
|
||||
protocol: linux.IpProto,
|
||||
/// flags is unused
|
||||
/// flags are currently unused
|
||||
flags: u32,
|
||||
) !*Sqe {
|
||||
const sqe = try self.get_sqe();
|
||||
|
|
@ -1711,7 +1711,7 @@ pub fn socket_direct(
|
|||
domain: linux.Af,
|
||||
socket_type: linux.Sock,
|
||||
protocol: linux.IpProto,
|
||||
/// flags is unused
|
||||
/// flags are currently unused
|
||||
flags: u32,
|
||||
file_index: u32,
|
||||
) !*Sqe {
|
||||
|
|
@ -1731,7 +1731,7 @@ pub fn socket_direct_alloc(
|
|||
domain: linux.Af,
|
||||
socket_type: linux.Sock,
|
||||
protocol: linux.IpProto,
|
||||
/// flags unused
|
||||
/// flags are currently unused
|
||||
flags: u32,
|
||||
) !*Sqe {
|
||||
const sqe = try self.get_sqe();
|
||||
|
|
@ -5377,8 +5377,8 @@ test "timeout (after a relative time)" {
|
|||
};
|
||||
defer ring.deinit();
|
||||
|
||||
const ms = 10;
|
||||
const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * 1000000 };
|
||||
const ms = 5;
|
||||
const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * 1_000_000 };
|
||||
|
||||
const started = try std.Io.Clock.awake.now(io);
|
||||
const sqe = try ring.timeout(0x55555555, &ts, 0, .{});
|
||||
|
|
@ -5394,9 +5394,9 @@ test "timeout (after a relative time)" {
|
|||
}, cqe);
|
||||
|
||||
// Tests should not depend on timings: skip test if outside margin.
|
||||
const margin = 5;
|
||||
const ms_margin = 5;
|
||||
const ms_elapsed = started.durationTo(stopped).toMilliseconds();
|
||||
if (ms_elapsed > margin) return error.SkipZigTest;
|
||||
if (ms_elapsed > ms_margin) return error.SkipZigTest;
|
||||
}
|
||||
|
||||
test "timeout (after a number of completions)" {
|
||||
|
|
@ -5802,7 +5802,7 @@ test "shutdown" {
|
|||
// Socket bound, expect shutdown to work
|
||||
{
|
||||
// TODO: update posix later to use Typed Flags
|
||||
const server = try posix.socket(address.any.family, @as(u32, @bitCast(linux.Sock{ .type = .stream, .flags = .{ .cloexec = true } })), 0);
|
||||
const server = try posix.socket(address.family, @as(u32, @bitCast(linux.Sock{ .type = .stream, .flags = .{ .cloexec = true } })), 0);
|
||||
defer posix.close(server);
|
||||
try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(u32, 1)));
|
||||
try posix.bind(server, addrAny(&address), @sizeOf(linux.sockaddr.in));
|
||||
|
|
@ -7460,7 +7460,7 @@ test "bind/listen/connect" {
|
|||
|
||||
const listen_fd = brk: {
|
||||
// Create socket
|
||||
_ = try ring.socket(1, @enumFromInt(addr.any.family), .{ .type = .stream, .flags = .{ .cloexec = true } }, @enumFromInt(proto), 0);
|
||||
_ = try ring.socket(1, @enumFromInt(addr.family), .{ .type = .stream, .flags = .{ .cloexec = true } }, @enumFromInt(proto), 0);
|
||||
try testing.expectEqual(1, try ring.submit());
|
||||
var cqe = try ring.copy_cqe();
|
||||
try testing.expectEqual(1, cqe.user_data);
|
||||
|
|
@ -7472,7 +7472,7 @@ test "bind/listen/connect" {
|
|||
var optval: u32 = 1;
|
||||
(try ring.setsockopt(2, listen_fd, .socket, .reuseaddr, mem.asBytes(&optval))).link_next();
|
||||
(try ring.setsockopt(3, listen_fd, .socket, .reuseport, mem.asBytes(&optval))).link_next();
|
||||
(try ring.bind(4, listen_fd, addrAny(&addr), @sizeOf(linux.sockaddr.in), 0)).link_next();
|
||||
(try ring.bind(4, listen_fd, addrAny(&addr), @sizeOf(linux.sockaddr.in))).link_next();
|
||||
_ = try ring.listen(5, listen_fd, 1);
|
||||
// Submit 4 operations
|
||||
try testing.expectEqual(4, try ring.submit());
|
||||
|
|
|
|||
|
|
@ -200,28 +200,28 @@ test "futex v1" {
|
|||
var rc: usize = 0;
|
||||
|
||||
// No-op wait, lock value is not expected value
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAIT, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
try expectEqual(.AGAIN, linux.errno(rc));
|
||||
|
||||
rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 2, null);
|
||||
rc = linux.futex_4arg(&lock, .{ .cmd = .WAIT, .private = true }, 2, null);
|
||||
try expectEqual(.AGAIN, linux.errno(rc));
|
||||
|
||||
// Short-fuse wait, timeout kicks in
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, .{ .timeout = &.{ .sec = 0, .nsec = 2 } }, null, 0);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAIT, .private = true }, 1, .{ .timeout = &.{ .sec = 0, .nsec = 2 } }, null, 0);
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
|
||||
rc = linux.futex_4arg(&lock.raw, .{ .cmd = .WAIT, .private = true }, 1, &.{ .sec = 0, .nsec = 2 });
|
||||
rc = linux.futex_4arg(&lock, .{ .cmd = .WAIT, .private = true }, 1, &.{ .sec = 0, .nsec = 2 });
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
|
||||
// Wakeup (no waiters)
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAKE, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
try expectEqual(0, rc);
|
||||
|
||||
rc = linux.futex_3arg(&lock.raw, .{ .cmd = .WAKE, .private = true }, 2);
|
||||
rc = linux.futex_3arg(&lock, .{ .cmd = .WAKE, .private = true }, 2);
|
||||
try expectEqual(0, rc);
|
||||
|
||||
// CMP_REQUEUE - val3 mismatch
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .CMP_REQUEUE, .private = true }, 2, .{ .val2 = 0 }, null, 99);
|
||||
rc = linux.futex(&lock, .{ .cmd = .CMP_REQUEUE, .private = true }, 2, .{ .val2 = 0 }, null, 99);
|
||||
try expectEqual(.AGAIN, linux.errno(rc));
|
||||
|
||||
// CMP_REQUEUE - requeue (but no waiters, so ... not much)
|
||||
|
|
@ -229,14 +229,14 @@ test "futex v1" {
|
|||
const val3 = 1;
|
||||
const wake_nr = 3;
|
||||
const requeue_max = std.math.maxInt(u31);
|
||||
var target_lock: std.atomic.Value(u32) = .init(1);
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .CMP_REQUEUE, .private = true }, wake_nr, .{ .val2 = requeue_max }, &target_lock.raw, val3);
|
||||
const target_lock: std.atomic.Value(u32) = .init(1);
|
||||
rc = linux.futex(&lock, .{ .cmd = .CMP_REQUEUE, .private = true }, wake_nr, .{ .val2 = requeue_max }, &target_lock, val3);
|
||||
try expectEqual(0, rc);
|
||||
}
|
||||
|
||||
// WAKE_OP - just to see if we can construct the arguments ...
|
||||
{
|
||||
var lock2: std.atomic.Value(u32) = .init(1);
|
||||
const lock2: std.atomic.Value(u32) = .init(1);
|
||||
const wake1_nr = 2;
|
||||
const wake2_nr = 3;
|
||||
const wake_op = linux.FUTEX_WAKE_OP{
|
||||
|
|
@ -247,29 +247,29 @@ test "futex v1" {
|
|||
.cmdarg = 5,
|
||||
};
|
||||
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_OP, .private = true }, wake1_nr, .{ .val2 = wake2_nr }, &lock2.raw, @bitCast(wake_op));
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAKE_OP, .private = true }, wake1_nr, .{ .val2 = wake2_nr }, &lock2, @bitCast(wake_op));
|
||||
try expectEqual(0, rc);
|
||||
}
|
||||
|
||||
// WAIT_BITSET
|
||||
{
|
||||
// val1 return early
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAIT_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff);
|
||||
try expectEqual(.AGAIN, linux.errno(rc));
|
||||
|
||||
// timeout wait
|
||||
const timeout: linux.timespec = .{ .sec = 0, .nsec = 2 };
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAIT_BITSET, .private = true }, 1, .{ .timeout = &timeout }, null, 0xfff);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAIT_BITSET, .private = true }, 1, .{ .timeout = &timeout }, null, 0xfff);
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
}
|
||||
|
||||
// WAKE_BITSET
|
||||
{
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff000);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0xfff000);
|
||||
try expectEqual(0, rc);
|
||||
|
||||
// bitmask must have at least 1 bit set:
|
||||
rc = linux.futex(&lock.raw, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
rc = linux.futex(&lock, .{ .cmd = .WAKE_BITSET, .private = true }, 2, .{ .timeout = null }, null, 0);
|
||||
try expectEqual(.INVAL, linux.errno(rc));
|
||||
}
|
||||
}
|
||||
|
|
@ -289,17 +289,17 @@ test "futex2_waitv" {
|
|||
const futexes: [3]linux.Futex2.WaitOne = .{
|
||||
.{
|
||||
.val = 1,
|
||||
.uaddr = @intFromPtr(&locks[0].raw),
|
||||
.uaddr = @intFromPtr(&locks[0]),
|
||||
.flags = .{ .size = .U32, .private = true },
|
||||
},
|
||||
.{
|
||||
.val = 1,
|
||||
.uaddr = @intFromPtr(&locks[1].raw),
|
||||
.uaddr = @intFromPtr(&locks[1]),
|
||||
.flags = .{ .size = .U32, .private = true },
|
||||
},
|
||||
.{
|
||||
.val = 1,
|
||||
.uaddr = @intFromPtr(&locks[2].raw),
|
||||
.uaddr = @intFromPtr(&locks[2]),
|
||||
.flags = .{ .size = .U32, .private = true },
|
||||
},
|
||||
};
|
||||
|
|
@ -316,7 +316,7 @@ test "futex2_waitv" {
|
|||
// Futex v2 API is only supported on recent kernels (v6.7), so skip tests if the syscalls
|
||||
// return ENOSYS.
|
||||
fn futex2_skip_if_unsupported() !void {
|
||||
const lock: u32 = 0;
|
||||
const lock: std.atomic.Value(u32) = .init(0);
|
||||
const rc = linux.futex2_wake(&lock, .empty, 1, .{ .size = .U32, .private = true });
|
||||
if (linux.errno(rc) == .NOSYS) {
|
||||
return error.SkipZigTest;
|
||||
|
|
@ -324,7 +324,7 @@ fn futex2_skip_if_unsupported() !void {
|
|||
}
|
||||
|
||||
test "futex2_wait" {
|
||||
var lock: std.atomic.Value(u32) = .init(1);
|
||||
const lock: std.atomic.Value(u32) = .init(1);
|
||||
var rc: usize = 0;
|
||||
const mask: linux.Futex2.Bitset = .{ .waiter1 = true };
|
||||
|
||||
|
|
@ -333,23 +333,23 @@ test "futex2_wait" {
|
|||
// The API for 8,16,64 bit futexes is defined, but as of kernel v6.14
|
||||
// (at least) they're not implemented.
|
||||
if (false) {
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U8, .private = true }, null, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, .{ .size = .U8, .private = true }, null, .MONOTONIC);
|
||||
try expectEqual(.INVAL, linux.errno(rc));
|
||||
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U16, .private = true }, null, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, .{ .size = .U16, .private = true }, null, .MONOTONIC);
|
||||
try expectEqual(.INVAL, linux.errno(rc));
|
||||
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, .{ .size = .U64, .private = true }, null, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, .{ .size = .U64, .private = true }, null, .MONOTONIC);
|
||||
try expectEqual(.INVAL, linux.errno(rc));
|
||||
}
|
||||
|
||||
const flags: linux.Futex2.Wait = .{ .size = .U32, .private = true };
|
||||
// no-wait, lock state mismatch
|
||||
rc = linux.futex2_wait(&lock.raw, 2, mask, flags, null, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 2, mask, flags, null, .MONOTONIC);
|
||||
try expectEqual(.AGAIN, linux.errno(rc));
|
||||
|
||||
// hit timeout on wait
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .MONOTONIC);
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
|
||||
// timeout is absolute
|
||||
|
|
@ -363,20 +363,20 @@ test "futex2_wait" {
|
|||
.sec = curr.sec,
|
||||
.nsec = curr.nsec + 2,
|
||||
};
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &timeout, .MONOTONIC);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, flags, &timeout, .MONOTONIC);
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
}
|
||||
|
||||
rc = linux.futex2_wait(&lock.raw, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .REALTIME);
|
||||
rc = linux.futex2_wait(&lock, 1, mask, flags, &.{ .sec = 0, .nsec = 2 }, .REALTIME);
|
||||
try expectEqual(.TIMEDOUT, linux.errno(rc));
|
||||
}
|
||||
|
||||
test "futex2_wake" {
|
||||
var lock: std.atomic.Value(u32) = .init(1);
|
||||
const lock: std.atomic.Value(u32) = .init(1);
|
||||
|
||||
try futex2_skip_if_unsupported();
|
||||
|
||||
const rc = linux.futex2_wake(&lock.raw, .fromInt(0xFF), 1, .{ .size = .U32, .private = true });
|
||||
const rc = linux.futex2_wake(&lock, .fromInt(0xFF), 1, .{ .size = .U32, .private = true });
|
||||
try expectEqual(0, rc);
|
||||
}
|
||||
|
||||
|
|
@ -391,12 +391,12 @@ test "futex2_requeue" {
|
|||
const futexes: [2]linux.Futex2.WaitOne = .{
|
||||
.{
|
||||
.val = 1,
|
||||
.uaddr = @intFromPtr(&locks[0].raw),
|
||||
.uaddr = @intFromPtr(&locks[0]),
|
||||
.flags = .{ .size = .U32, .private = true },
|
||||
},
|
||||
.{
|
||||
.val = 1,
|
||||
.uaddr = @intFromPtr(&locks[1].raw),
|
||||
.uaddr = @intFromPtr(&locks[1]),
|
||||
.flags = .{ .size = .U32, .private = true },
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3992,7 +3992,7 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S
|
|||
|
||||
const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;
|
||||
var stat = mem.zeroes(Stat);
|
||||
switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
|
||||
switch (errno(fstatat_sym(dirfd, pathname, &stat, @bitCast(flags)))) {
|
||||
.SUCCESS => return stat,
|
||||
.INVAL => unreachable,
|
||||
.BADF => unreachable, // Always a race condition.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue