@@ -117,7 +117,7 @@ impl Hash for Timespec {
117
117
#[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
118
118
mod inner {
119
119
use crate :: fmt;
120
- use crate :: sync:: atomic:: { AtomicBool , AtomicU64 , Ordering } ;
120
+ use crate :: sync:: atomic:: { AtomicU64 , Ordering } ;
121
121
use crate :: sys:: cvt;
122
122
use crate :: sys_common:: mul_div_u64;
123
123
use crate :: time:: Duration ;
@@ -232,15 +232,19 @@ mod inner {
232
232
}
233
233
234
234
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.
236
242
static INFO_BITS : AtomicU64 = AtomicU64 :: new ( 0 ) ;
237
243
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) ;
244
248
}
245
249
246
250
// ... otherwise learn for ourselves ...
@@ -252,15 +256,7 @@ mod inner {
252
256
unsafe {
253
257
mach_timebase_info ( & mut info) ;
254
258
}
255
-
256
- // This is racy, but the race should be against other threads trying to
257
- // write the same value.
258
259
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 ) ;
264
260
info
265
261
}
266
262
0 commit comments