exocore_core/time/
atomic_instant.rs1use std::{sync::atomic::AtomicU64, time::Duration};
2
3use wasm_timer::Instant;
4
5pub struct AtomicInstant {
6 reference: Instant,
7 delta: AtomicU64,
8}
9
10impl AtomicInstant {
11 pub fn new() -> Self {
12 Self {
13 reference: Instant::now(),
14 delta: AtomicU64::new(0),
15 }
16 }
17
18 pub fn get(&self) -> Instant {
19 self.reference + Duration::from_nanos(self.delta.load(std::sync::atomic::Ordering::Relaxed))
20 }
21
22 pub fn elapsed(&self) -> Duration {
23 Instant::now() - self.get()
24 }
25
26 pub fn update(&self, now: Instant) {
27 let delta = now - self.reference;
28 self.delta.store(
29 delta.as_nanos() as u64,
30 std::sync::atomic::Ordering::Relaxed,
31 );
32 }
33
34 pub fn update_now(&self) {
35 self.update(Instant::now())
36 }
37}
38
39impl Default for AtomicInstant {
40 fn default() -> Self {
41 Self::new()
42 }
43}
44
45impl From<Instant> for AtomicInstant {
46 fn from(instant: Instant) -> Self {
47 AtomicInstant {
48 reference: instant,
49 delta: AtomicU64::new(0),
50 }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use std::thread::sleep;
57
58 use super::*;
59
60 #[test]
61 fn test_atomic_instant() {
62 let ai = AtomicInstant::new();
63
64 sleep(Duration::from_millis(100));
65 let elapsed = ai.elapsed();
66 assert!(
67 elapsed >= Duration::from_millis(100),
68 "elapsed: {elapsed:?}"
69 );
70
71 ai.update_now();
72 let elapsed = ai.elapsed();
73 assert!(elapsed < Duration::from_millis(100), "elapsed: {elapsed:?}");
74 }
75}