Skip to content

Commit 57465d9

Browse files
committed
use AtomicU64::fetch_update instead of handrolled RMW-loop
1 parent 2b512cc commit 57465d9

File tree

2 files changed

+10
-14
lines changed

2 files changed

+10
-14
lines changed

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@
234234
#![feature(atomic_mut_ptr)]
235235
#![feature(auto_traits)]
236236
#![feature(bench_black_box)]
237+
#![feature(bool_to_option)]
237238
#![feature(box_syntax)]
238239
#![feature(c_unwind)]
239240
#![feature(c_variadic)]

library/std/src/time/monotonic.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,15 @@ pub mod inner {
3737
// This could be a problem for programs that call instants at intervals greater
3838
// than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true.
3939
let packed = (secs << 32) | nanos;
40-
let mut old = mono.load(Relaxed);
41-
loop {
42-
if old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2 {
43-
match mono.compare_exchange_weak(old, packed, Relaxed, Relaxed) {
44-
Ok(_) => return raw,
45-
Err(x) => {
46-
old = x;
47-
continue;
48-
}
49-
}
50-
} else {
40+
let updated = mono.fetch_update(Relaxed, Relaxed, |old| {
41+
(old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed)
42+
});
43+
match updated {
44+
Ok(_) => raw,
45+
Err(newer) => {
5146
// Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
5247
// passed in value and the 64bits loaded from the atomic
53-
let seconds_lower = old >> 32;
48+
let seconds_lower = newer >> 32;
5449
let mut seconds_upper = secs & 0xffff_ffff_0000_0000;
5550
if secs & 0xffff_ffff > seconds_lower {
5651
// Backslide caused the lower 32bit of the seconds part to wrap.
@@ -69,8 +64,8 @@ pub mod inner {
6964
seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000);
7065
}
7166
let secs = seconds_upper | seconds_lower;
72-
let nanos = old as u32;
73-
return ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap();
67+
let nanos = newer as u32;
68+
ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
7469
}
7570
}
7671
}

0 commit comments

Comments
 (0)