@@ -20,6 +20,32 @@ enum InstantKind {
20
20
Virtual { nanoseconds : u64 } ,
21
21
}
22
22
23
+ impl Instant {
24
+ pub fn checked_add ( & self , duration : Duration ) -> Option < Instant > {
25
+ match self . kind {
26
+ InstantKind :: Host ( instant) =>
27
+ instant. checked_add ( duration) . map ( |i| Instant { kind : InstantKind :: Host ( i) } ) ,
28
+ InstantKind :: Virtual { nanoseconds } =>
29
+ u128:: from ( nanoseconds)
30
+ . checked_add ( duration. as_nanos ( ) )
31
+ . and_then ( |n| u64:: try_from ( n) . ok ( ) )
32
+ . map ( |nanoseconds| Instant { kind : InstantKind :: Virtual { nanoseconds } } ) ,
33
+ }
34
+ }
35
+
36
+ pub fn duration_since ( & self , earlier : Instant ) -> Duration {
37
+ match ( & self . kind , earlier. kind ) {
38
+ ( InstantKind :: Host ( instant) , InstantKind :: Host ( earlier) ) =>
39
+ instant. duration_since ( earlier) ,
40
+ (
41
+ InstantKind :: Virtual { nanoseconds } ,
42
+ InstantKind :: Virtual { nanoseconds : earlier } ,
43
+ ) => Duration :: from_nanos ( nanoseconds. saturating_sub ( earlier) ) ,
44
+ _ => panic ! ( "all `Instant` must be of the same kind" ) ,
45
+ }
46
+ }
47
+ }
48
+
23
49
/// A monotone clock used for `Instant` simulation.
24
50
#[ derive( Debug ) ]
25
51
pub struct Clock {
@@ -50,24 +76,14 @@ impl Clock {
50
76
Self { kind }
51
77
}
52
78
53
- /// Get the current time relative to this clock.
54
- pub fn get ( & self ) -> Duration {
55
- match & self . kind {
56
- ClockKind :: Host { time_anchor } =>
57
- StdInstant :: now ( ) . saturating_duration_since ( * time_anchor) ,
58
- ClockKind :: Virtual { nanoseconds } =>
59
- Duration :: from_nanos ( nanoseconds. load ( Ordering :: Relaxed ) ) ,
60
- }
61
- }
62
-
63
79
/// Let the time pass for a small interval.
64
80
pub fn tick ( & self ) {
65
81
match & self . kind {
66
82
ClockKind :: Host { .. } => {
67
83
// Time will pass without us doing anything.
68
84
}
69
85
ClockKind :: Virtual { nanoseconds } => {
70
- nanoseconds. fetch_add ( NANOSECOND_PER_BASIC_BLOCK , Ordering :: Relaxed ) ;
86
+ nanoseconds. fetch_add ( NANOSECOND_PER_BASIC_BLOCK , Ordering :: SeqCst ) ;
71
87
}
72
88
}
73
89
}
@@ -78,54 +94,26 @@ impl Clock {
78
94
ClockKind :: Host { .. } => std:: thread:: sleep ( duration) ,
79
95
ClockKind :: Virtual { nanoseconds } => {
80
96
// Just pretend that we have slept for some time.
81
- nanoseconds. fetch_add ( duration. as_nanos ( ) . try_into ( ) . unwrap ( ) , Ordering :: Relaxed ) ;
97
+ nanoseconds. fetch_add ( duration. as_nanos ( ) . try_into ( ) . unwrap ( ) , Ordering :: SeqCst ) ;
82
98
}
83
99
}
84
100
}
85
101
86
- /// Compute `now + duration` relative to this clock .
87
- pub fn get_time_relative ( & self , duration : Duration ) -> Option < Instant > {
102
+ /// Return the `anchor` instant, to convert between monotone instants and durations relative to the anchor .
103
+ pub fn anchor ( & self ) -> Instant {
88
104
match & self . kind {
89
- ClockKind :: Host { .. } =>
90
- StdInstant :: now ( )
91
- . checked_add ( duration)
92
- . map ( |instant| Instant { kind : InstantKind :: Host ( instant) } ) ,
93
- ClockKind :: Virtual { nanoseconds } =>
94
- nanoseconds
95
- . load ( Ordering :: Relaxed )
96
- . checked_add ( duration. as_nanos ( ) . try_into ( ) . unwrap ( ) )
97
- . map ( |nanoseconds| Instant { kind : InstantKind :: Virtual { nanoseconds } } ) ,
105
+ ClockKind :: Host { time_anchor } => Instant { kind : InstantKind :: Host ( * time_anchor) } ,
106
+ ClockKind :: Virtual { .. } => Instant { kind : InstantKind :: Virtual { nanoseconds : 0 } } ,
98
107
}
99
108
}
100
109
101
- /// Compute `start + duration` relative to this clock where `start` is the instant of time when
102
- /// this clock was created.
103
- pub fn get_time_absolute ( & self , duration : Duration ) -> Option < Instant > {
110
+ pub fn now ( & self ) -> Instant {
104
111
match & self . kind {
105
- ClockKind :: Host { time_anchor } =>
106
- time_anchor
107
- . checked_add ( duration)
108
- . map ( |instant| Instant { kind : InstantKind :: Host ( instant) } ) ,
109
- ClockKind :: Virtual { .. } =>
110
- Some ( Instant {
111
- kind : InstantKind :: Virtual {
112
- nanoseconds : duration. as_nanos ( ) . try_into ( ) . unwrap ( ) ,
113
- } ,
114
- } ) ,
115
- }
116
- }
117
-
118
- /// Returns the duration until the given instant.
119
- pub fn duration_until ( & self , instant : & Instant ) -> Duration {
120
- match ( & instant. kind , & self . kind ) {
121
- ( InstantKind :: Host ( instant) , ClockKind :: Host { .. } ) =>
122
- instant. saturating_duration_since ( StdInstant :: now ( ) ) ,
123
- (
124
- InstantKind :: Virtual { nanoseconds } ,
125
- ClockKind :: Virtual { nanoseconds : current_ns } ,
126
- ) =>
127
- Duration :: from_nanos ( nanoseconds. saturating_sub ( current_ns. load ( Ordering :: Relaxed ) ) ) ,
128
- _ => panic ! ( ) ,
112
+ ClockKind :: Host { .. } => Instant { kind : InstantKind :: Host ( StdInstant :: now ( ) ) } ,
113
+ ClockKind :: Virtual { nanoseconds } =>
114
+ Instant {
115
+ kind : InstantKind :: Virtual { nanoseconds : nanoseconds. load ( Ordering :: SeqCst ) } ,
116
+ } ,
129
117
}
130
118
}
131
119
}
0 commit comments