Skip to content

Commit 59c06e9

Browse files
committed
Switch to using a single atomic and treating 0 as 'uninitialized'
1 parent e4cf24b commit 59c06e9

File tree

1 file changed

+12
-16
lines changed

1 file changed

+12
-16
lines changed

library/std/src/sys/unix/time.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl Hash for Timespec {
117117
#[cfg(any(target_os = "macos", target_os = "ios"))]
118118
mod inner {
119119
use crate::fmt;
120-
use crate::sync::atomic::{AtomicBool, AtomicU64, Ordering};
120+
use crate::sync::atomic::{AtomicU64, Ordering};
121121
use crate::sys::cvt;
122122
use crate::sys_common::mul_div_u64;
123123
use crate::time::Duration;
@@ -232,15 +232,19 @@ mod inner {
232232
}
233233

234234
fn info() -> mach_timebase_info {
235-
static INITIALIZED: AtomicBool = AtomicBool::new(false);
235+
// INFO_BITS conceptually is an `Option<mach_timebase_info>`. We can do
236+
// this in 64 bits because we know 0 is never a valid value for the
237+
// `denom` field.
238+
//
239+
// Encoding this as a single `AtomicU64` allows us to use `Relaxed`
240+
// operations, as we are only interested in in the effects on a single
241+
// memory location.
236242
static INFO_BITS: AtomicU64 = AtomicU64::new(0);
237243

238-
// If a previous thread has initialized `INFO_BITS`, use that.
239-
if INITIALIZED.load(Ordering::Acquire) {
240-
// Note: `Relaxed` is correct here and below -- the `Acquire` /
241-
// `Release` pair used for `INITIALIZED` ensures this load can see
242-
// the corresponding store below.
243-
return info_from_bits(INFO_BITS.load(Ordering::Relaxed));
244+
// If a previous thread has initialized `INFO_BITS`, use it.
245+
let info_bits = INFO_BITS.load(Ordering::Relaxed);
246+
if info_bits != 0 {
247+
return info_from_bits(info_bits);
244248
}
245249

246250
// ... otherwise learn for ourselves ...
@@ -252,15 +256,7 @@ mod inner {
252256
unsafe {
253257
mach_timebase_info(&mut info);
254258
}
255-
256-
// This is racy, but the race should be against other threads trying to
257-
// write the same value.
258259
INFO_BITS.store(info_to_bits(info), Ordering::Relaxed);
259-
260-
// The `Release` here "publishes" the store of `INFO_BITS` to other
261-
// threads (which do a `INITIALIZED.load(Acquire)`) despite it being
262-
// read/written w/ `Relaxed`.
263-
INITIALIZED.store(true, Ordering::Release);
264260
info
265261
}
266262

0 commit comments

Comments
 (0)