feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.nowWindows
fn nowWindows(clock: Io.Clock) Io.Timestamp
File
Code
fn nowWindows(clock: Io.Clock) Io.Timestamp {
switch (clock) {
.real => {
// and uses the NTFS/Windows epoch, which is 1601-01-01.
const epoch_ns = std.time.epoch.windows * std.time.ns_per_s;
return .{ .nanoseconds = @as(i96, windows.ntdll.RtlGetSystemTimePrecise()) * 100 + epoch_ns };
},
.awake, .boot => {
// (a read-only page of info updated and mapped by the kernel to all processes):
// 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
const qpf: u64 = qpf: {
var qpf: windows.LARGE_INTEGER = undefined;
assert(windows.ntdll.RtlQueryPerformanceFrequency(&qpf).toBool());
break :qpf @bitCast(qpf);
};
const qpc: u64 = qpc: {
var qpc: windows.LARGE_INTEGER = undefined;
assert(windows.ntdll.RtlQueryPerformanceCounter(&qpc).toBool());
break :qpc @bitCast(qpc);
};
// https://github.com/microsoft/STL/blob/785143a0c73f030238ef618890fd4d6ae2b3a3a0/stl/inc/chrono#L694-L701
const common_qpf = 10_000_000;
if (qpf == common_qpf) return .{ .nanoseconds = qpc * (std.time.ns_per_s / common_qpf) };
const scale = @as(u64, std.time.ns_per_s << 32) / @as(u32, @intCast(qpf));
const result = (@as(u96, qpc) * scale) >> 32;
return .{ .nanoseconds = @intCast(result) };
},
.cpu_process => {
const handle = windows.GetCurrentProcess();
var times: windows.KERNEL_USER_TIMES = undefined;
if (windows.ntdll.NtQueryInformationProcess(
handle,
.Times,
×,
@sizeOf(windows.KERNEL_USER_TIMES),
null,
) != .SUCCESS) return .zero;
const sum = @as(i96, times.UserTime) + @as(i96, times.KernelTime);
return .{ .nanoseconds = sum * 100 };
},
.cpu_thread => {
const handle = windows.GetCurrentThread();
var times: windows.KERNEL_USER_TIMES = undefined;
if (windows.ntdll.NtQueryInformationThread(
handle,
.Times,
×,
@sizeOf(windows.KERNEL_USER_TIMES),
null,
) != .SUCCESS) return .zero;
const sum = @as(i96, times.UserTime) + @as(i96, times.KernelTime);
return .{ .nanoseconds = sum * 100 };
},
}
}