diff options
| author | The8472 <git@infinite-source.de> | 2021-09-17 18:42:16 +0200 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2021-09-17 18:54:24 +0200 |
| commit | 57465d9c1bb979a64c6e7c5220b4ab20291547aa (patch) | |
| tree | 407293f7f3b24af9f04bd35855eb65f39cc624ce | |
| parent | 2b512cc329a87202003d41828fe8f6f2fbeaf720 (diff) | |
| download | rust-57465d9c1bb979a64c6e7c5220b4ab20291547aa.tar.gz rust-57465d9c1bb979a64c6e7c5220b4ab20291547aa.zip | |
use AtomicU64::fetch_update instead of handrolled RMW-loop
| -rw-r--r-- | library/std/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/std/src/time/monotonic.rs | 23 |
2 files changed, 10 insertions, 14 deletions
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 83c6ba0e6ea..f1640ab8b1e 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -234,6 +234,7 @@ #![feature(atomic_mut_ptr)] #![feature(auto_traits)] #![feature(bench_black_box)] +#![feature(bool_to_option)] #![feature(box_syntax)] #![feature(c_unwind)] #![feature(c_variadic)] diff --git a/library/std/src/time/monotonic.rs b/library/std/src/time/monotonic.rs index fb1c8932756..198ae739b55 100644 --- a/library/std/src/time/monotonic.rs +++ b/library/std/src/time/monotonic.rs @@ -37,20 +37,15 @@ pub mod inner { // 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. let packed = (secs << 32) | nanos; - let mut old = mono.load(Relaxed); - loop { - if old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2 { - match mono.compare_exchange_weak(old, packed, Relaxed, Relaxed) { - Ok(_) => return raw, - Err(x) => { - old = x; - continue; - } - } - } else { + let updated = mono.fetch_update(Relaxed, Relaxed, |old| { + (old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed) + }); + match updated { + Ok(_) => raw, + Err(newer) => { // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the // 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; if secs & 0xffff_ffff > seconds_lower { // 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); } let secs = seconds_upper | seconds_lower; - let nanos = old as u32; - return ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap(); + let nanos = newer as u32; + ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap() } } } |
