1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::time::timestamp::Timestamp;
use core::time::Duration;
pub trait Clock {
fn get_time(&self) -> Timestamp;
}
#[derive(Clone, Copy, Debug)]
pub struct NoopClock;
impl Clock for NoopClock {
fn get_time(&self) -> Timestamp {
unsafe { Timestamp::from_duration(Duration::from_micros(1)) }
}
}
#[cfg(any(test, feature = "std"))]
mod std_clock {
use super::*;
use std::time::Instant;
impl<C: 'static + Clock> Clock for &'static std::thread::LocalKey<C> {
fn get_time(&self) -> Timestamp {
self.with(|clock| clock.get_time())
}
}
#[derive(Clone, Copy, Debug)]
pub struct StdClock {
epoch: Instant,
}
impl Default for StdClock {
fn default() -> Self {
Self {
epoch: Instant::now(),
}
}
}
impl StdClock {
pub const fn new(epoch: Instant) -> Self {
Self { epoch }
}
}
impl Clock for StdClock {
fn get_time(&self) -> Timestamp {
unsafe { Timestamp::from_duration(self.epoch.elapsed()) }
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn monotonicity_test() {
let clock = StdClock::default();
let ts1 = clock.get_time();
::std::thread::sleep(Duration::from_millis(50));
let ts2 = clock.get_time();
assert!(ts2 - ts1 >= Duration::from_millis(50));
}
}
#[cfg(any(test, feature = "std"))]
pub use std_clock::*;
#[cfg(any(test, feature = "testing"))]
pub mod testing {
use super::{Duration, Timestamp};
#[derive(Clone, Copy, Debug)]
pub struct Clock {
current_timestamp: Timestamp,
}
impl Default for Clock {
fn default() -> Self {
Self {
current_timestamp: unsafe { Timestamp::from_duration(Duration::from_micros(1)) },
}
}
}
impl super::Clock for Clock {
fn get_time(&self) -> Timestamp {
self.current_timestamp
}
}
impl Clock {
pub fn inc_by(&mut self, duration: Duration) {
self.current_timestamp += duration
}
}
}