use AtomicU64::fetch_update instead of handrolled RMW-loop

This commit is contained in:
The8472 2021-09-17 18:42:16 +02:00
parent 2b512cc329
commit 57465d9c1b
2 changed files with 10 additions and 14 deletions

View File

@ -234,6 +234,7 @@
#![feature(atomic_mut_ptr)] #![feature(atomic_mut_ptr)]
#![feature(auto_traits)] #![feature(auto_traits)]
#![feature(bench_black_box)] #![feature(bench_black_box)]
#![feature(bool_to_option)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(c_unwind)] #![feature(c_unwind)]
#![feature(c_variadic)] #![feature(c_variadic)]

View File

@ -37,20 +37,15 @@ pub mod inner {
// This could be a problem for programs that call instants at intervals greater // This could be a problem for programs that call instants at intervals greater
// than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true. // than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true.
let packed = (secs << 32) | nanos; let packed = (secs << 32) | nanos;
let mut old = mono.load(Relaxed); let updated = mono.fetch_update(Relaxed, Relaxed, |old| {
loop { (old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed)
if old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2 { });
match mono.compare_exchange_weak(old, packed, Relaxed, Relaxed) { match updated {
Ok(_) => return raw, Ok(_) => raw,
Err(x) => { Err(newer) => {
old = x;
continue;
}
}
} else {
// Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
// passed in value and the 64bits loaded from the atomic // passed in value and the 64bits loaded from the atomic
let seconds_lower = old >> 32; let seconds_lower = newer >> 32;
let mut seconds_upper = secs & 0xffff_ffff_0000_0000; let mut seconds_upper = secs & 0xffff_ffff_0000_0000;
if secs & 0xffff_ffff > seconds_lower { if secs & 0xffff_ffff > seconds_lower {
// Backslide caused the lower 32bit of the seconds part to wrap. // Backslide caused the lower 32bit of the seconds part to wrap.
@ -69,8 +64,8 @@ pub mod inner {
seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000); seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000);
} }
let secs = seconds_upper | seconds_lower; let secs = seconds_upper | seconds_lower;
let nanos = old as u32; let nanos = newer as u32;
return ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap(); ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
} }
} }
} }