authorgravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-04-30 20:44:22-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-24 21:40:08-04:00
logbb4689411563d0f4d0327aefdf36074c54bf7f83
tree2d69eba4a8fd01ba7ef7efb54052b5878d735575
parent4b1a8464715a9b2af1d9024694282883f3346482

Add `std.time.nanoTimestamp` function


1 files changed, 19 insertions(+), 13 deletions(-)

lib/std/time.zig+19-13
...@@ -58,16 +58,25 @@ pub fn timestamp() u64 {...@@ -58,16 +58,25 @@ pub fn timestamp() u64 {
58/// Get the posix timestamp, UTC, in milliseconds58/// Get the posix timestamp, UTC, in milliseconds
59/// TODO audit this function. is it possible to return an error?59/// TODO audit this function. is it possible to return an error?
60pub fn milliTimestamp() u64 {60pub fn milliTimestamp() u64 {
61 return @divFloor(nanoTimestamp(), millisecond);
62}
63
64/// Get the posix timestamp, UTC, in nanoseconds
65///
66/// On windows this only has a granularity of 100 nanoseconds.
67///
68/// TODO audit this function. is it possible to return an error?
69pub fn nanoTimestamp() u64 {
61 if (is_windows) {70 if (is_windows) {
62 //FileTime has a granularity of 100 nanoseconds71 //FileTime has a granularity of 100 nanoseconds
63 // and uses the NTFS/Windows epoch72 // and uses the NTFS/Windows epoch
64 var ft: os.windows.FILETIME = undefined;73 var ft: os.windows.FILETIME = undefined;
65 os.windows.kernel32.GetSystemTimeAsFileTime(&ft);74 os.windows.kernel32.GetSystemTimeAsFileTime(&ft);
66 const hns_per_ms = (ns_per_s / 100) / ms_per_s;75 const ns_per_hns = 100;
67 const epoch_adj = epoch.windows * ms_per_s;76 const epoch_adj = epoch.windows * ns_per_s;
6877
69 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;78 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
70 return @divFloor(ft64, hns_per_ms) - -epoch_adj;79 return (ft64 * hns_per_ms) - -epoch_adj;
71 }80 }
72 if (builtin.os.tag == .wasi and !builtin.link_libc) {81 if (builtin.os.tag == .wasi and !builtin.link_libc) {
73 var ns: os.wasi.timestamp_t = undefined;82 var ns: os.wasi.timestamp_t = undefined;
...@@ -76,25 +85,22 @@ pub fn milliTimestamp() u64 {...@@ -76,25 +85,22 @@ pub fn milliTimestamp() u64 {
76 const err = os.wasi.clock_time_get(os.wasi.CLOCK_REALTIME, 1, &ns);85 const err = os.wasi.clock_time_get(os.wasi.CLOCK_REALTIME, 1, &ns);
77 assert(err == os.wasi.ESUCCESS);86 assert(err == os.wasi.ESUCCESS);
7887
79 const ns_per_ms = 1000;88 return ns;
80 return @divFloor(ns, ns_per_ms);
81 }89 }
82 if (comptime std.Target.current.isDarwin()) {90 if (comptime std.Target.current.isDarwin()) {
83 var tv: os.darwin.timeval = undefined;91 var mts: os.darwin.mach_timespec_t = undefined;
84 var err = os.darwin.gettimeofday(&tv, null);92 var err = os.darwin.clock_get_time(os.darwin.CALENDAR_CLOCK, &mts);
85 assert(err == 0);93 assert(err == 0);
86 const sec_ms = tv.tv_sec * ms_per_s;94 const sec_ns = @as(u64, mts.tv_sec * ns_per_s);
87 const usec_ms = @divFloor(tv.tv_usec, us_per_s / ms_per_s);95 return sec_ns + @intCast(u64, mts.tv_nsec);
88 return @intCast(u64, sec_ms + usec_ms);
89 }96 }
90 var ts: os.timespec = undefined;97 var ts: os.timespec = undefined;
91 //From what I can tell there's no reason clock_gettime98 //From what I can tell there's no reason clock_gettime
92 // should ever fail for us with CLOCK_REALTIME,99 // should ever fail for us with CLOCK_REALTIME,
93 // seccomp aside.100 // seccomp aside.
94 os.clock_gettime(os.CLOCK_REALTIME, &ts) catch unreachable;101 os.clock_gettime(os.CLOCK_REALTIME, &ts) catch unreachable;
95 const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s;102 const sec_ns = @intCast(u64, ts.tv_sec) * ns_per_s;
96 const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s);103 return sec_ns + @intCast(u64, ts.tv_nsec);
97 return sec_ms + nsec_ms;
98}104}
99105
100/// Multiples of a base unit (nanoseconds)106/// Multiples of a base unit (nanoseconds)