@@ -37,20 +37,15 @@ pub mod inner {
37
37
// This could be a problem for programs that call instants at intervals greater
38
38
// than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true.
39
39
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) => {
51
46
// Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
52
47
// passed in value and the 64bits loaded from the atomic
53
- let seconds_lower = old >> 32 ;
48
+ let seconds_lower = newer >> 32 ;
54
49
let mut seconds_upper = secs & 0xffff_ffff_0000_0000 ;
55
50
if secs & 0xffff_ffff > seconds_lower {
56
51
// Backslide caused the lower 32bit of the seconds part to wrap.
@@ -69,8 +64,8 @@ pub mod inner {
69
64
seconds_upper = seconds_upper. wrapping_add ( 0x1_0000_0000 ) ;
70
65
}
71
66
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 ( )
74
69
}
75
70
}
76
71
}
0 commit comments