| ... | ... | @@ -242,15 +242,24 @@ pub const Timer = struct { |
| 242 | 242 | |
| 243 | 243 | fn nativeDurationToNanos(self: Timer, duration: u64) u64 { |
| 244 | 244 | if (is_windows) { |
| 245 | | return @divFloor(duration * ns_per_s, self.frequency); |
| 245 | return safeMulDiv(duration, ns_per_s, self.frequency); |
| 246 | 246 | } |
| 247 | 247 | if (comptime std.Target.current.isDarwin()) { |
| 248 | | return @divFloor(duration * self.frequency.numer, self.frequency.denom); |
| 248 | return safeMulDiv(duration, self.frequency.numer, self.frequency.denom); |
| 249 | 249 | } |
| 250 | 250 | return duration; |
| 251 | 251 | } |
| 252 | 252 | }; |
| 253 | 253 | |
| 254 | // Calculate (a * b) / c without risk of overflowing too early because of the |
| 255 | // multiplication. |
| 256 | fn safeMulDiv(a: u64, b: u64, c: u64) u64 { |
| 257 | const q = a / c; |
| 258 | const r = a % c; |
| 259 | // (a * b) / c == (a / c) * b + ((a % c) * b) / c |
| 260 | return (q * b) + (r * b) / c; |
| 261 | } |
| 262 | |
| 254 | 263 | test "sleep" { |
| 255 | 264 | sleep(1); |
| 256 | 265 | } |