| ... | @@ -61,6 +61,32 @@ pub fn milliTimestamp() u64 { | ... | @@ -61,6 +61,32 @@ pub fn milliTimestamp() u64 { |
| 61 | return @divFloor(nanoTimestamp(), millisecond); | 61 | return @divFloor(nanoTimestamp(), millisecond); |
| 62 | } | 62 | } |
| 63 | | 63 | |
| | 64 | const DarwinTimeStart = struct { |
| | 65 | timebase: os.darwin.mach_timebase_info_data, |
| | 66 | inittime: os.darwin.timespec, |
| | 67 | initclock: u64, |
| | 68 | }; |
| | 69 | |
| | 70 | var _timestart: ?DarwinTimeStart = null; |
| | 71 | |
| | 72 | pub 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 | |
| 64 | /// Get the posix timestamp, UTC, in nanoseconds | 90 | /// Get the posix timestamp, UTC, in nanoseconds |
| 65 | /// | 91 | /// |
| 66 | /// On windows this only has a granularity of 100 nanoseconds. | 92 | /// On windows this only has a granularity of 100 nanoseconds. |
| ... | @@ -76,7 +102,7 @@ pub fn nanoTimestamp() u64 { | ... | @@ -76,7 +102,7 @@ pub fn nanoTimestamp() u64 { |
| 76 | const epoch_adj = epoch.windows * ns_per_s; | 102 | const epoch_adj = epoch.windows * ns_per_s; |
| 77 | | 103 | |
| 78 | const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; | 104 | 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; |
| 80 | } | 106 | } |
| 81 | if (builtin.os.tag == .wasi and !builtin.link_libc) { | 107 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 82 | var ns: os.wasi.timestamp_t = undefined; | 108 | var ns: os.wasi.timestamp_t = undefined; |
| ... | @@ -88,11 +114,17 @@ pub fn nanoTimestamp() u64 { | ... | @@ -88,11 +114,17 @@ pub fn nanoTimestamp() u64 { |
| 88 | return ns; | 114 | return ns; |
| 89 | } | 115 | } |
| 90 | if (comptime std.Target.current.isDarwin()) { | 116 | if (comptime std.Target.current.isDarwin()) { |
| 91 | var mts: os.darwin.mach_timespec_t = undefined; | 117 | // https://stackoverflow.com/a/21352348 |
| 92 | var err = os.darwin.clock_get_time(os.darwin.CALENDAR_CLOCK, &mts); | 118 | const timestart = if (_timestart) |timestart| timestart else _init_time_for_darwin(); |
| 93 | assert(err == 0); | 119 | |
| 94 | const sec_ns = @as(u64, mts.tv_sec * ns_per_s); | 120 | const clock: u64 = os.darwin.mach_absolute_time() - timestart.initclock; |
| 95 | return sec_ns + @intCast(u64, mts.tv_nsec); | 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; |
| 96 | } | 128 | } |
| 97 | var ts: os.timespec = undefined; | 129 | var ts: os.timespec = undefined; |
| 98 | //From what I can tell there's no reason clock_gettime | 130 | //From what I can tell there's no reason clock_gettime |