about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThom Chiovoloni <chiovolonit@gmail.com>2020-10-08 17:04:32 -0700
committerThom Chiovoloni <chiovolonit@gmail.com>2020-10-08 17:04:32 -0700
commit4f3722051092bfe33ec87836e8dd4d6d155c1fc1 (patch)
treeb68b7ef7232d5de9c1ddf04f19878ce5a7b083ce
parent59c06e9e40c39aeec955fb2359f810285c262c34 (diff)
downloadrust-4f3722051092bfe33ec87836e8dd4d6d155c1fc1.tar.gz
rust-4f3722051092bfe33ec87836e8dd4d6d155c1fc1.zip
Implement the same optimization in windows/time
-rw-r--r--library/std/src/sys/windows/time.rs36
1 files changed, 17 insertions, 19 deletions
diff --git a/library/std/src/sys/windows/time.rs b/library/std/src/sys/windows/time.rs
index 900260169c7..91e4f765484 100644
--- a/library/std/src/sys/windows/time.rs
+++ b/library/std/src/sys/windows/time.rs
@@ -165,7 +165,7 @@ fn intervals2dur(intervals: u64) -> Duration {
 
 mod perf_counter {
     use super::NANOS_PER_SEC;
-    use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+    use crate::sync::atomic::{AtomicU64, Ordering};
     use crate::sys::c;
     use crate::sys::cvt;
     use crate::sys_common::mul_div_u64;
@@ -197,27 +197,25 @@ mod perf_counter {
     }
 
     fn frequency() -> c::LARGE_INTEGER {
-        static mut FREQUENCY: c::LARGE_INTEGER = 0;
-        static STATE: AtomicUsize = AtomicUsize::new(0);
-
+        // Either the cached result of `QueryPerformanceFrequency` or `0` for
+        // uninitialized. Storing this as a single `AtomicU64` allows us to use
+        // `Relaxed` operations, as we are only interested in the effects on a
+        // single memory location.
+        static FREQUENCY: AtomicU64 = AtomicU64::new(0);
+
+        let cached = FREQUENCY.load(Ordering::Relaxed);
+        // If a previous thread has filled in this global state, use that.
+        if cached != 0 {
+            return cached as c::LARGE_INTEGER;
+        }
+        // ... otherwise learn for ourselves ...
+        let mut frequency = 0;
         unsafe {
-            // If a previous thread has filled in this global state, use that.
-            if STATE.load(SeqCst) == 2 {
-                return FREQUENCY;
-            }
-
-            // ... otherwise learn for ourselves ...
-            let mut frequency = 0;
             cvt(c::QueryPerformanceFrequency(&mut frequency)).unwrap();
-
-            // ... and attempt to be the one thread that stores it globally for
-            // all other threads
-            if STATE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() {
-                FREQUENCY = frequency;
-                STATE.store(2, SeqCst);
-            }
-            frequency
         }
+
+        FREQUENCY.store(frequency as u64, Ordering::Relaxed);
+        frequency
     }
 
     fn query() -> c::LARGE_INTEGER {