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 {...@@ -153,15 +153,9 @@ pub const Timer = struct {
153 }153 }
154154
155 /// Reads the timer value since start or the last reset in nanoseconds155 /// 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 {
157 var clock = clockNative() - self.start_time;157 var clock = clockNative() - self.start_time;
158 if (builtin.os == .windows) {158 return self.nativeDurationToNanos(clock);
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;
165 }159 }
166160
167 /// Resets the timer value to 0/now.161 /// Resets the timer value to 0/now.
...@@ -172,7 +166,7 @@ pub const Timer = struct {...@@ -172,7 +166,7 @@ pub const Timer = struct {
172 /// Returns the current value of the timer in nanoseconds, then resets it166 /// Returns the current value of the timer in nanoseconds, then resets it
173 pub fn lap(self: *Timer) u64 {167 pub fn lap(self: *Timer) u64 {
174 var now = clockNative();168 var now = clockNative();
175 var lap_time = self.read();169 var lap_time = self.nativeDurationToNanos(now - self.start_time);
176 self.start_time = now;170 self.start_time = now;
177 return lap_time;171 return lap_time;
178 }172 }
...@@ -188,6 +182,16 @@ pub const Timer = struct {...@@ -188,6 +182,16 @@ pub const Timer = struct {
188 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;182 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
189 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);183 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
190 }184 }
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 }
191};195};
192196
193test "sleep" {197test "sleep" {