Zig 0.17.0-dev (Split by item) This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig standard library.
std › Io › Threaded › nowWindows Private Function nowWindows Doc Source Private Function std.Io.Threaded.nowWindows
fn nowWindows (clock : Io .Clock ) Io .Timestamp Params File Io/Threaded.zig: 11777
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846 fn nowWindows (clock : Io .Clock ) Io .Timestamp {
switch (clock ) {
.real => {
// RtlGetSystemTimePrecise() has a granularity of 100 nanoseconds
// 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 => {
// We don't need to cache QPF as it's internally just a memory read to KUSER_SHARED_DATA
// (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 );
};
// QPC on windows doesn't fail on >= XP/2000 and includes time suspended.
const qpc : u64 = qpc : {
var qpc : windows .LARGE_INTEGER = undefined ;
assert (windows .ntdll .RtlQueryPerformanceCounter (&qpc ).toBool ());
break :qpc @bitCast (qpc );
};
// 10Mhz (1 qpc tick every 100ns) is a common enough QPF value that we can optimize on it.
// 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 ) };
// Convert to ns using fixed point.
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 ;
// https://github.com/reactos/reactos/blob/master/ntoskrnl/ps/query.c#L442-L485
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 ;
// https://github.com/reactos/reactos/blob/master/ntoskrnl/ps/query.c#L2971-L3019
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 };
},
}
}