in time/src/lib.rs [86:222]
fn refresh(&self) {
match self.state.load(Ordering::Relaxed) {
UNINITIALIZED => {
if self
.state
.compare_exchange(
UNINITIALIZED,
REFRESHING,
Ordering::Acquire,
Ordering::Acquire,
)
.is_ok()
{
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
unsafe {
libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
}
self.coarse.store(
Instant {
inner: Seconds::from(ts),
},
Ordering::Release,
);
self.precise.store(
Instant {
inner: Nanoseconds::from(ts),
},
Ordering::Release,
);
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
unsafe {
libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
}
self.coarse_unix.store(
UnixInstant {
inner: Seconds::from(ts),
},
Ordering::Release,
);
self.precise_unix.store(
UnixInstant {
inner: Nanoseconds::from(ts),
},
Ordering::Release,
);
// finalize initialization
self.state.store(INITIALIZED, Ordering::Release);
}
// if we raced, we should block until the other thread completes
// initialization
while self.state.load(Ordering::Relaxed) != INITIALIZED {}
}
INITIALIZED => {
if self
.state
.compare_exchange(
INITIALIZED,
REFRESHING,
Ordering::Acquire,
Ordering::Acquire,
)
.is_ok()
{
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
unsafe {
libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
}
let now: Instant<Nanoseconds<u64>> = Instant {
inner: Nanoseconds::from(ts),
};
let previous = self.precise.load(Ordering::Acquire);
// this makes sure we're truly monotonic even if there are
// platform bugs
if now > previous {
self.precise.store(now, Ordering::Release);
self.coarse.store(
Instant {
inner: Seconds::from(ts),
},
Ordering::Release,
);
}
// update unix time
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
unsafe {
libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
}
// unconditionally set unix time, which may move backwards
self.coarse_unix.store(
UnixInstant {
inner: Seconds::from(ts),
},
Ordering::Release,
);
self.precise_unix.store(
UnixInstant {
inner: Nanoseconds::from(ts),
},
Ordering::Release,
);
// finalize refresh
self.state.store(INITIALIZED, Ordering::Relaxed);
}
// if we raced, we should block until the other thread completes
// initialization
while self.state.load(Ordering::Relaxed) != INITIALIZED {}
}
REFRESHING => {
// if we raced, we should block until the other thread completes
// initialization
while self.state.load(Ordering::Relaxed) != INITIALIZED {}
}
_ => {
unreachable!()
}
}
}