]> git.lizzy.rs Git - rust.git/commitdiff
[Windows] Work around non-monotonic clocks in the self-profiler
authorWesley Wiser <wwiser@gmail.com>
Thu, 22 Nov 2018 18:05:25 +0000 (13:05 -0500)
committerWesley Wiser <wwiser@gmail.com>
Sun, 25 Nov 2018 02:38:35 +0000 (21:38 -0500)
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

src/librustc/util/profiling.rs

index 37073b6e82080a616db922205dc26b990e4d5310..1f050439764914adf3ac737816d0dd957bb599de 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::fs;
 use std::io::{self, StdoutLock, Write};
-use std::time::Instant;
+use std::time::{Duration, Instant};
 
 macro_rules! define_categories {
     ($($name:ident,)*) => {
@@ -197,7 +197,20 @@ pub fn end_activity(&mut self, category: ProfileCategory) {
     }
 
     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();