commit 4431ca28b86b2e8efad4a6340e0eac07f5a09ac5 (tree)
parent eec244c5a2ea391d62164c657086472208118672
Author: Jake Greenfield <jake@greenfield.sh>
Date: Tue, 24 Mar 2026 21:30:27 -0400
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
Diffstat:
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -11448,7 +11448,7 @@ fn clockResolution(userdata: ?*anyopaque, clock: Io.Clock) Io.Clock.ResolutionEr
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
var qpf: windows.LARGE_INTEGER = undefined;
- if (windows.ntdll.RtlQueryPerformanceFrequency(&qpf).toBool()) {
+ if (!windows.ntdll.RtlQueryPerformanceFrequency(&qpf).toBool()) {
recoverableOsBugDetected();
return .zero;
}
@@ -17677,7 +17677,8 @@ fn timeoutToWindowsInterval(timeout: Io.Timeout) ?windows.LARGE_INTEGER {
.duration => |d| nowWindows(clock).addDuration(d.raw),
.deadline => |d| d.raw,
};
- return @intCast(@max(@divTrunc(deadline.nanoseconds, 100), 0));
+ const epoch_ns = std.time.epoch.windows * std.time.ns_per_s;
+ return @intCast(@max(@divTrunc(deadline.nanoseconds - epoch_ns, 100), 0));
},
.awake, .boot => {
const duration = switch (timeout) {