authorgravatar for 48419392+heidezomp@users.noreply.github.comHeide Onas Auri <48419392+heidezomp@users.noreply.github.com> 2020-02-24 00:25:52+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-02-23 18:25:52-05:00
log907c5589ae20d1b2a73acf26c9d67139dfe3bfb9
treeb3943503d2a10c24545ddec92368fe66a5cc1faa
parentcfe1fbad0f6a47fa0f5798df1423702b84bf34aa
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

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

lib/std/time.zig+13-9
......@@ -153,15 +153,9 @@ pub const Timer = struct {
153153 }
154154
155155 /// Reads the timer value since start or the last reset in nanoseconds
156 pub fn read(self: *Timer) u64 {
156 pub fn read(self: Timer) u64 {
157157 var clock = clockNative() - self.start_time;
158 if (builtin.os == .windows) {
159 return @divFloor(clock * ns_per_s, self.frequency);
160 }
161 if (comptime std.Target.current.isDarwin()) {
162 return @divFloor(clock * self.frequency.numer, self.frequency.denom);
163 }
164 return clock;
158 return self.nativeDurationToNanos(clock);
165159 }
166160
167161 /// Resets the timer value to 0/now.
......@@ -172,7 +166,7 @@ pub const Timer = struct {
172166 /// Returns the current value of the timer in nanoseconds, then resets it
173167 pub fn lap(self: *Timer) u64 {
174168 var now = clockNative();
175 var lap_time = self.read();
169 var lap_time = self.nativeDurationToNanos(now - self.start_time);
176170 self.start_time = now;
177171 return lap_time;
178172 }
......@@ -188,6 +182,16 @@ pub const Timer = struct {
188182 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
189183 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
190184 }
185
186 fn nativeDurationToNanos(self: Timer, duration: u64) u64 {
187 if (builtin.os == .windows) {
188 return @divFloor(duration * ns_per_s, self.frequency);
189 }
190 if (comptime std.Target.current.isDarwin()) {
191 return @divFloor(duration * self.frequency.numer, self.frequency.denom);
192 }
193 return duration;
194 }
191195};
192196
193197test "sleep" {