From 907c5589ae20d1b2a73acf26c9d67139dfe3bfb9 Mon Sep 17 00:00:00 2001 From: Heide Onas Auri <48419392+heidezomp@users.noreply.github.com> Date: Mon, 24 Feb 2020 00:25:52 +0100 Subject: [PATCH] std.time.Timer.lap: only read system time once (#4533) Calling Timer.lap queried the system time twice; once to compute the lap time and once to reset the timer. This can lead to time discrepancies between actual and computed durations when summing the result of Timer.lap in a loop. This commit fixes that. also fix Timer.read to not require a pointer --- lib/std/time.zig | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/std/time.zig b/lib/std/time.zig index a5f66122cb3a..63d3ecce18eb 100644 --- a/lib/std/time.zig +++ b/lib/std/time.zig @@ -153,15 +153,9 @@ pub const Timer = struct { } /// Reads the timer value since start or the last reset in nanoseconds - pub fn read(self: *Timer) u64 { + pub fn read(self: Timer) u64 { var clock = clockNative() - self.start_time; - if (builtin.os == .windows) { - return @divFloor(clock * ns_per_s, self.frequency); - } - if (comptime std.Target.current.isDarwin()) { - return @divFloor(clock * self.frequency.numer, self.frequency.denom); - } - return clock; + return self.nativeDurationToNanos(clock); } /// Resets the timer value to 0/now. @@ -172,7 +166,7 @@ pub const Timer = struct { /// Returns the current value of the timer in nanoseconds, then resets it pub fn lap(self: *Timer) u64 { var now = clockNative(); - var lap_time = self.read(); + var lap_time = self.nativeDurationToNanos(now - self.start_time); self.start_time = now; return lap_time; } @@ -188,6 +182,16 @@ pub const Timer = struct { os.clock_gettime(monotonic_clock_id, &ts) catch unreachable; return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec); } + + fn nativeDurationToNanos(self: Timer, duration: u64) u64 { + if (builtin.os == .windows) { + return @divFloor(duration * ns_per_s, self.frequency); + } + if (comptime std.Target.current.isDarwin()) { + return @divFloor(duration * self.frequency.numer, self.frequency.denom); + } + return duration; + } }; test "sleep" {