authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2025-02-12 17:56:37+03:30
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-13 16:55:58+01:00
logbffbc918ee2b349923ca2e7b9b5c8ff8fa1d0cd0
tree3242d7c4ebd58f3621ea2e7153f91cad5d2c92a7
parentd12123a88cf56428874b359cb63acb8618dfbcfd

std.time: more precise `nanoTimestamp` in windows


4 files changed, 7 insertions(+), 28 deletions(-)

lib/std/os/windows/kernel32.zig-5
...@@ -656,9 +656,4 @@ pub extern "kernel32" fn SetLastError(...@@ -656,9 +656,4 @@ pub extern "kernel32" fn SetLastError(
656656
657// Everything Else657// Everything Else
658658
659// TODO:
660// Wrapper around KUSER_SHARED_DATA.SystemTime.
661// Much better to use NtQuerySystemTime or NtQuerySystemTimePrecise for guaranteed 0.1ns precision.
662pub extern "kernel32" fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: *FILETIME) callconv(.winapi) void;
663
664pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.winapi) void;659pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.winapi) void;
lib/std/os/windows/ntdll.zig+1
...@@ -92,6 +92,7 @@ pub extern "ntdll" fn RtlVirtualUnwind(...@@ -92,6 +92,7 @@ pub extern "ntdll" fn RtlVirtualUnwind(
92 EstablisherFrame: *DWORD64,92 EstablisherFrame: *DWORD64,
93 ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,93 ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,
94) callconv(.winapi) *EXCEPTION_ROUTINE;94) callconv(.winapi) *EXCEPTION_ROUTINE;
95pub extern "ntdll" fn RtlGetSystemTimePrecise() callconv(.winapi) LARGE_INTEGER;
95pub extern "ntdll" fn NtQueryInformationFile(96pub extern "ntdll" fn NtQueryInformationFile(
96 FileHandle: HANDLE,97 FileHandle: HANDLE,
97 IoStatusBlock: *IO_STATUS_BLOCK,98 IoStatusBlock: *IO_STATUS_BLOCK,
lib/std/posix.zig+4-18
...@@ -5693,7 +5693,10 @@ pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;...@@ -5693,7 +5693,10 @@ pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
56935693
5694pub fn clock_gettime(clock_id: clockid_t) ClockGetTimeError!timespec {5694pub fn clock_gettime(clock_id: clockid_t) ClockGetTimeError!timespec {
5695 var tp: timespec = undefined;5695 var tp: timespec = undefined;
5696 if (native_os == .wasi and !builtin.link_libc) {5696
5697 if (native_os == .windows) {
5698 @compileError("Windows does not support POSIX; use Windows-specific API or cross-platform std.time API");
5699 } else if (native_os == .wasi and !builtin.link_libc) {
5697 var ts: timestamp_t = undefined;5700 var ts: timestamp_t = undefined;
5698 switch (system.clock_time_get(clock_id, 1, &ts)) {5701 switch (system.clock_time_get(clock_id, 1, &ts)) {
5699 .SUCCESS => {5702 .SUCCESS => {
...@@ -5707,23 +5710,6 @@ pub fn clock_gettime(clock_id: clockid_t) ClockGetTimeError!timespec {...@@ -5707,23 +5710,6 @@ pub fn clock_gettime(clock_id: clockid_t) ClockGetTimeError!timespec {
5707 }5710 }
5708 return tp;5711 return tp;
5709 }5712 }
5710 if (native_os == .windows) {
5711 if (clock_id == .REALTIME) {
5712 var ft: windows.FILETIME = undefined;
5713 windows.kernel32.GetSystemTimeAsFileTime(&ft);
5714 // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch.
5715 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
5716 const ft_per_s = std.time.ns_per_s / 100;
5717 tp = .{
5718 .sec = @as(i64, @intCast(ft64 / ft_per_s)) + std.time.epoch.windows,
5719 .nsec = @as(c_long, @intCast(ft64 % ft_per_s)) * 100,
5720 };
5721 return tp;
5722 } else {
5723 // TODO POSIX implementation of CLOCK.MONOTONIC on Windows.
5724 return error.UnsupportedClock;
5725 }
5726 }
57275713
5728 switch (errno(system.clock_gettime(clock_id, &tp))) {5714 switch (errno(system.clock_gettime(clock_id, &tp))) {
5729 .SUCCESS => return tp,5715 .SUCCESS => return tp,
lib/std/time.zig+2-5
...@@ -47,13 +47,10 @@ pub fn microTimestamp() i64 {...@@ -47,13 +47,10 @@ pub fn microTimestamp() i64 {
47pub fn nanoTimestamp() i128 {47pub fn nanoTimestamp() i128 {
48 switch (builtin.os.tag) {48 switch (builtin.os.tag) {
49 .windows => {49 .windows => {
50 // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch,50 // RtlGetSystemTimePrecise() has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch,
51 // which is 1601-01-01.51 // which is 1601-01-01.
52 const epoch_adj = epoch.windows * (ns_per_s / 100);52 const epoch_adj = epoch.windows * (ns_per_s / 100);
53 var ft: windows.FILETIME = undefined;53 return @as(i128, windows.ntdll.RtlGetSystemTimePrecise() + epoch_adj) * 100;
54 windows.kernel32.GetSystemTimeAsFileTime(&ft);
55 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
56 return @as(i128, @as(i64, @bitCast(ft64)) + epoch_adj) * 100;
57 },54 },
58 .wasi => {55 .wasi => {
59 var ns: std.os.wasi.timestamp_t = undefined;56 var ns: std.os.wasi.timestamp_t = undefined;