On Windows, the high-resolution timestamp api doesn't seem to always be
monotonic. This can cause panics when the self-profiler uses the
`Instant` api to find elapsed time.
Work around this by detecting the case where now is less than the start
time and just use 0 elapsed ticks as the measurement.
Fixes #51648
use std::fs;
use std::io::{self, StdoutLock, Write};
use std::fs;
use std::io::{self, StdoutLock, Write};
+use std::time::{Duration, Instant};
macro_rules! define_categories {
($($name:ident,)*) => {
macro_rules! define_categories {
($($name:ident,)*) => {
}
fn stop_timer(&mut self) -> u64 {
}
fn stop_timer(&mut self) -> u64 {
- let elapsed = self.current_timer.elapsed();
+ let elapsed = if cfg!(windows) {
+ // On Windows, timers don't always appear to be monotonic (see #51648)
+ // which can lead to panics when calculating elapsed time.
+ // Work around this by testing to see if the current time is less than
+ // our recorded time, and if it is, just returning 0.
+ let now = Instant::now();
+ if self.current_timer >= now {
+ Duration::new(0, 0)
+ } else {
+ self.current_timer.elapsed()
+ }
+ } else {
+ self.current_timer.elapsed()
+ };
self.current_timer = Instant::now();
self.current_timer = Instant::now();