authorgravatar for leroycepearson@geemili.xyzLeRoyce Pearson <leroycepearson@geemili.xyz> 2020-04-30 22:45:54-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-24 21:40:08-04:00
log7586ce0023e309fa5c86b67fe13d476f04a290f0
treed77a6fc7ed4973e1c035fe513f68e7df973ff60f
parentbb4689411563d0f4d0327aefdf36074c54bf7f83

Implement a faster way to get nanoseconds on darwin


1 files changed, 38 insertions(+), 6 deletions(-)

lib/std/time.zig+38-6
......@@ -61,6 +61,32 @@ pub fn milliTimestamp() u64 {
6161 return @divFloor(nanoTimestamp(), millisecond);
6262}
6363
64const DarwinTimeStart = struct {
65 timebase: os.darwin.mach_timebase_info_data,
66 inittime: os.darwin.timespec,
67 initclock: u64,
68};
69
70var _timestart: ?DarwinTimeStart = null;
71
72pub fn _init_time_for_darwin() DarwinTimeStart {
73 var micro: os.darwin.timeval = undefined;
74 var timestart: DarwinTimeStart = undefined;
75
76 var err = os.darwin.mach_timebase_info(&timestart.timebase);
77 assert(err == 0);
78
79 err = os.darwin.gettimeofday(&micro, null);
80 assert(err == 0);
81
82 timestart.initclock = os.darwin.mach_absolute_time();
83 timestart.inittime.tv_sec = micro.tv_sec;
84 timestart.inittime.tv_nsec = micro.tv_usec * 1000;
85
86 _timestart = timestart;
87 return timestart;
88}
89
6490/// Get the posix timestamp, UTC, in nanoseconds
6591///
6692/// On windows this only has a granularity of 100 nanoseconds.
......@@ -76,7 +102,7 @@ pub fn nanoTimestamp() u64 {
76102 const epoch_adj = epoch.windows * ns_per_s;
77103
78104 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
79 return (ft64 * hns_per_ms) - -epoch_adj;
105 return (ft64 * ns_per_hns) - -epoch_adj;
80106 }
81107 if (builtin.os.tag == .wasi and !builtin.link_libc) {
82108 var ns: os.wasi.timestamp_t = undefined;
......@@ -88,11 +114,17 @@ pub fn nanoTimestamp() u64 {
88114 return ns;
89115 }
90116 if (comptime std.Target.current.isDarwin()) {
91 var mts: os.darwin.mach_timespec_t = undefined;
92 var err = os.darwin.clock_get_time(os.darwin.CALENDAR_CLOCK, &mts);
93 assert(err == 0);
94 const sec_ns = @as(u64, mts.tv_sec * ns_per_s);
95 return sec_ns + @intCast(u64, mts.tv_nsec);
117 // https://stackoverflow.com/a/21352348
118 const timestart = if (_timestart) |timestart| timestart else _init_time_for_darwin();
119
120 const clock: u64 = os.darwin.mach_absolute_time() - timestart.initclock;
121 const nano = clock * @divFloor(@as(u64, timestart.timebase.number), @as(u64, timestart.timebase.denom));
122
123 var future = timestart.inittime;
124 const tv_sec_nsec = @intCast(u64, timestart.inittime.tv_sec) * ns_per_s;
125 const tv_nsec = @intCast(u64, timestart.inittime.tv_nsec);
126
127 return tv_sec_nsec + tv_nsec + nano;
96128 }
97129 var ts: os.timespec = undefined;
98130 //From what I can tell there's no reason clock_gettime