authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-21 07:24:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:51-07:00
log0107e584ef4c8071b9ab71f20aae83a5cfb91921
tree5f3011d6e191b3bcb622cb5f9e941c345a805758
parentd257b1337a1b0cbe5b2694518017216aa1d2ef1a

std.Io.Threaded: implement Windows futex functions


1 files changed, 32 insertions(+), 34 deletions(-)

lib/std/Io/Threaded.zig+32-34
......@@ -4880,10 +4880,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
48804880 .FAULT => unreachable, // ptr was invalid
48814881 else => unreachable,
48824882 };
4883 return;
4884 }
4885
4886 if (native_os.isDarwin()) {
4883 } else if (native_os.isDarwin()) {
48874884 const c = std.c;
48884885 const flags: c.UL = .{
48894886 .op = .COMPARE_AND_WAIT,
......@@ -4907,10 +4904,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
49074904 .TIMEDOUT => unreachable,
49084905 else => unreachable,
49094906 };
4910 return;
4911 }
4912
4913 if (builtin.cpu.arch.isWasm()) {
4907 } else if (builtin.cpu.arch.isWasm()) {
49144908 comptime assert(builtin.cpu.has(.wasm, .atomics));
49154909 try t.checkCancel();
49164910 const timeout: i64 = -1;
......@@ -4933,10 +4927,16 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
49334927 2 => assert(!is_debug), // timeout
49344928 else => assert(!is_debug),
49354929 }
4936 return;
4930 } else if (is_windows) {
4931 try t.checkCancel();
4932 switch (windows.ntdll.RtlWaitOnAddress(ptr, &expect, @sizeOf(@TypeOf(expect)), null)) {
4933 .SUCCESS => {},
4934 .CANCELLED => return error.Canceled,
4935 else => recoverableOsBugDetected(),
4936 }
4937 } else {
4938 @compileError("TODO");
49374939 }
4938
4939 @compileError("TODO");
49404940}
49414941
49424942pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) void {
......@@ -4954,10 +4954,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
49544954 .FAULT => unreachable, // ptr was invalid
49554955 else => unreachable,
49564956 };
4957 return;
4958 }
4959
4960 if (native_os.isDarwin()) {
4957 } else if (native_os.isDarwin()) {
49614958 const c = std.c;
49624959 const flags: c.UL = .{
49634960 .op = .COMPARE_AND_WAIT,
......@@ -4980,10 +4977,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
49804977 .TIMEDOUT => unreachable,
49814978 else => unreachable,
49824979 };
4983 return;
4984 }
4985
4986 if (builtin.cpu.arch.isWasm()) {
4980 } else if (builtin.cpu.arch.isWasm()) {
49874981 comptime assert(builtin.cpu.has(.wasm, .atomics));
49884982 const timeout: i64 = -1;
49894983 const signed_expect: i32 = @bitCast(expect);
......@@ -5005,10 +4999,14 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
50054999 2 => assert(!is_debug), // timeout
50065000 else => assert(!is_debug),
50075001 }
5008 return;
5002 } else if (is_windows) {
5003 switch (windows.ntdll.RtlWaitOnAddress(ptr, &expect, @sizeOf(@TypeOf(expect)), null)) {
5004 .SUCCESS, .CANCELLED => {},
5005 else => recoverableOsBugDetected(),
5006 }
5007 } else {
5008 @compileError("TODO");
50095009 }
5010
5011 @compileError("TODO");
50125010}
50135011
50145012pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect: u32, timeout: Io.Duration) void {
......@@ -5028,9 +5026,9 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:
50285026 else => unreachable,
50295027 };
50305028 return;
5029 } else {
5030 @compileError("TODO");
50315031 }
5032
5033 @compileError("TODO");
50345032}
50355033
50365034pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
......@@ -5049,10 +5047,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
50495047 .FAULT => {}, // pointer became invalid while doing the wake
50505048 else => unreachable,
50515049 };
5052 return;
5053 }
5054
5055 if (native_os.isDarwin()) {
5050 } else if (native_os.isDarwin()) {
50565051 const c = std.c;
50575052 const flags: c.UL = .{
50585053 .op = .COMPARE_AND_WAIT,
......@@ -5071,9 +5066,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
50715066 else => assert(!is_debug),
50725067 }
50735068 }
5074 }
5075
5076 if (builtin.cpu.arch.isWasm()) {
5069 } else if (builtin.cpu.arch.isWasm()) {
50775070 comptime assert(builtin.cpu.has(.wasm, .atomics));
50785071 assert(max_waiters != 0);
50795072 const woken_count = asm volatile (
......@@ -5086,10 +5079,15 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
50865079 [waiters] "r" (max_waiters),
50875080 );
50885081 _ = woken_count; // can be 0 when linker flag 'shared-memory' is not enabled
5089 return;
5082 } else if (is_windows) {
5083 assert(max_waiters != 0);
5084 switch (max_waiters) {
5085 1 => windows.ntdll.RtlWakeAddressSingle(ptr),
5086 else => windows.ntdll.RtlWakeAddressAll(ptr),
5087 }
5088 } else {
5089 @compileError("TODO");
50905090 }
5091
5092 @compileError("TODO");
50935091}
50945092
50955093/// A thread-safe logical boolean value which can be `set` and `unset`.