authorgravatar for jake@greenfield.shJake Greenfield <jake@greenfield.sh> 2026-03-24 21:30:27-04:00
committergravatar for jake@greenfield.shJake Greenfield <jake@greenfield.sh> 2026-03-24 21:33:27-04:00
log4431ca28b86b2e8efad4a6340e0eac07f5a09ac5
treee67647c4717ce4207728305a2eb68455d3ce284d
parenteec244c5a2ea391d62164c657086472208118672

fix Windows clock handling

Address two separate but related issues: - Return value of `RtlQueryPerformanceFrequency` was used inconsistently; it returns a nonzero value to indicate success. - `timeoutToWindowsInterval` wasn't converting absolute deadlines back to the Windows epoch before passing them to the system, which meant that values (in the Unix epoch) were always in the distant past, so sleeps would return immediately. Fixes #31653

1 files changed, 3 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+3-2
...@@ -11448,7 +11448,7 @@ fn clockResolution(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.ResolutionEr...@@ -11448,7 +11448,7 @@ fn clockResolution(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.ResolutionEr
11448 // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data11448 // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data
11449 // https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm11449 // https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
11450 var qpf: windows.LARGE_INTEGER = undefined;11450 var qpf: windows.LARGE_INTEGER = undefined;
11451 if (windows.ntdll.RtlQueryPerformanceFrequency(&qpf).toBool()) {11451 if (!windows.ntdll.RtlQueryPerformanceFrequency(&qpf).toBool()) {
11452 recoverableOsBugDetected();11452 recoverableOsBugDetected();
11453 return .zero;11453 return .zero;
11454 }11454 }
...@@ -17677,7 +17677,8 @@ fn timeoutToWindowsInterval(timeout: Io.Timeout) ?windows.LARGE_INTEGER {...@@ -17677,7 +17677,8 @@ fn timeoutToWindowsInterval(timeout: Io.Timeout) ?windows.LARGE_INTEGER {
17677 .duration => |d| nowWindows(clock).addDuration(d.raw),17677 .duration => |d| nowWindows(clock).addDuration(d.raw),
17678 .deadline => |d| d.raw,17678 .deadline => |d| d.raw,
17679 };17679 };
17680 return @intCast(@max(@divTrunc(deadline.nanoseconds, 100), 0));17680 const epoch_ns = std.time.epoch.windows * std.time.ns_per_s;
17681 return @intCast(@max(@divTrunc(deadline.nanoseconds - epoch_ns, 100), 0));
17681 },17682 },
17682 .awake, .boot => {17683 .awake, .boot => {
17683 const duration = switch (timeout) {17684 const duration = switch (timeout) {