@@ -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