Skip to content

Commit dce1c45

Browse files
committed
[Windows] Work around non-monotonic clocks in the self-profiler
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
1 parent b319715 commit dce1c45

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

src/librustc/util/profiling.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use session::config::Options;
1212

1313
use std::fs;
1414
use std::io::{self, StdoutLock, Write};
15-
use std::time::Instant;
15+
use std::time::{Duration, Instant};
1616

1717
macro_rules! define_categories {
1818
($($name:ident,)*) => {
@@ -197,7 +197,20 @@ impl SelfProfiler {
197197
}
198198

199199
fn stop_timer(&mut self) -> u64 {
200-
let elapsed = self.current_timer.elapsed();
200+
let elapsed = if cfg!(windows) {
201+
// On Windows, timers don't always appear to be monotonic (see #51648)
202+
// which can lead to panics when calculating elapsed time.
203+
// Work around this by testing to see if the current time is less than
204+
// our recorded time, and if it is, just returning 0.
205+
let now = Instant::now();
206+
if self.current_timer >= now {
207+
Duration::new(0, 0)
208+
} else {
209+
self.current_timer.elapsed()
210+
}
211+
} else {
212+
self.current_timer.elapsed()
213+
};
201214

202215
self.current_timer = Instant::now();
203216

0 commit comments

Comments
 (0)