1use crate::rand::{GlobalRng, Rng};
6use futures_util::{select_biased, FutureExt};
7use naive_timer::Timer;
8use spin::Mutex;
9#[doc(no_inline)]
10pub use std::time::{Duration, Instant};
11use std::{future::Future, sync::Arc, time::SystemTime};
12
13pub mod error;
14mod interval;
15mod sleep;
16mod system_time;
17
18pub use self::interval::{interval, interval_at, Interval, MissedTickBehavior};
19pub use self::sleep::{sleep, sleep_until, Sleep};
20
21pub(crate) struct TimeRuntime {
22 handle: TimeHandle,
23}
24
25impl TimeRuntime {
26 pub fn new(rand: &GlobalRng) -> Self {
27 let base_time = SystemTime::UNIX_EPOCH
29 + Duration::from_secs(
30 60 * 60 * 24 * 365 * (2022 - 1970)
31 + rand.with(|rng| rng.gen_range(0..60 * 60 * 24 * 365)),
32 );
33 let handle = TimeHandle {
34 timer: Arc::new(Mutex::new(Timer::default())),
35 clock: Arc::new(Clock::new(base_time)),
36 };
37 TimeRuntime { handle }
38 }
39
40 pub fn handle(&self) -> &TimeHandle {
41 &self.handle
42 }
43
44 pub fn advance_to_next_event(&self) -> bool {
46 let mut timer = self.handle.timer.lock();
47 if let Some(mut time) = timer.next() {
48 time += Duration::from_nanos(50);
54 timer.expire(time);
55 self.handle.clock.set_elapsed(time);
56 true
57 } else {
58 false
59 }
60 }
61
62 #[allow(dead_code)]
63 pub fn now_instant(&self) -> Instant {
65 self.handle.now_instant()
66 }
67}
68
69#[derive(Clone)]
71pub struct TimeHandle {
72 timer: Arc<Mutex<Timer>>,
73 clock: Arc<Clock>,
74}
75
76impl TimeHandle {
77 pub fn current() -> Self {
79 crate::context::current(|h| h.time.clone())
80 }
81
82 pub fn try_current() -> Option<Self> {
84 crate::context::try_current(|h| h.time.clone())
85 }
86
87 pub fn now_instant(&self) -> Instant {
89 self.clock.now_instant()
90 }
91
92 pub fn now_time(&self) -> SystemTime {
94 self.clock.now_time()
95 }
96
97 pub fn elapsed(&self) -> Duration {
99 self.clock.elapsed()
100 }
101
102 pub fn advance(&self, duration: Duration) {
104 let time = self.clock.advance(duration);
105 self.timer.lock().expire(time);
106 }
107
108 pub fn sleep(&self, duration: Duration) -> Sleep {
112 self.sleep_until(self.clock.now_instant() + duration)
113 }
114
115 pub fn sleep_until(&self, deadline: Instant) -> Sleep {
119 let min_deadline = self.clock.now_instant() + Duration::from_millis(1);
120 Sleep {
121 handle: self.clone(),
122 deadline: deadline.max(min_deadline),
123 }
124 }
125
126 pub fn timeout<T: Future>(
129 &self,
130 duration: Duration,
131 future: T,
132 ) -> impl Future<Output = Result<T::Output, error::Elapsed>> {
133 let timeout = self.sleep(duration);
134 async move {
135 select_biased! {
136 res = future.fuse() => Ok(res),
137 _ = timeout.fuse() => Err(error::Elapsed),
138 }
139 }
140 }
141
142 pub(crate) fn add_timer_at(
143 &self,
144 deadline: Instant,
145 callback: impl FnOnce() + Send + Sync + 'static,
146 ) {
147 let mut timer = self.timer.lock();
148 timer.add(deadline - self.clock.base_instant(), |_| callback());
149 }
150
151 pub(crate) fn add_timer(&self, dur: Duration, callback: impl FnOnce() + Send + Sync + 'static) {
152 self.add_timer_at(self.clock.now_instant() + dur, callback);
153 }
154}
155
156pub fn timeout<T: Future>(
158 duration: Duration,
159 future: T,
160) -> impl Future<Output = Result<T::Output, error::Elapsed>> {
161 let handle = TimeHandle::current();
162 handle.timeout(duration, future)
163}
164
165#[cfg_attr(docsrs, doc(cfg(madsim)))]
170pub fn advance(duration: Duration) {
171 let handle = TimeHandle::current();
172 handle.advance(duration);
173}
174
175struct Clock {
176 inner: Mutex<ClockInner>,
177}
178
179#[derive(Debug)]
180struct ClockInner {
181 base_time: std::time::SystemTime,
183 base_instant: std::time::Instant,
184 advance: Duration,
186}
187
188impl Clock {
189 fn new(base_time: SystemTime) -> Self {
190 let clock = ClockInner {
191 base_time,
192 base_instant: unsafe { std::mem::zeroed() },
193 advance: Duration::default(),
194 };
195 Clock {
196 inner: Mutex::new(clock),
197 }
198 }
199
200 fn set_elapsed(&self, time: Duration) {
201 let mut inner = self.inner.lock();
202 inner.advance = time;
203 }
204
205 fn elapsed(&self) -> Duration {
206 let inner = self.inner.lock();
207 inner.advance
208 }
209
210 fn advance(&self, duration: Duration) -> Duration {
211 let mut inner = self.inner.lock();
212 inner.advance += duration;
213 inner.advance
214 }
215
216 fn base_instant(&self) -> Instant {
217 let inner = self.inner.lock();
218 inner.base_instant
219 }
220
221 fn now_instant(&self) -> Instant {
222 let inner = self.inner.lock();
223 inner.base_instant + inner.advance
224 }
225
226 fn now_time(&self) -> SystemTime {
227 let inner = self.inner.lock();
228 inner.base_time + inner.advance
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use super::*;
235 use crate::runtime::Runtime;
236
237 #[test]
238 fn time() {
239 let runtime = Runtime::new();
240 runtime.block_on(async {
241 let t0 = Instant::now();
243 sleep(Duration::default()).await;
244 assert!(t0.elapsed() >= Duration::from_millis(1));
245
246 let t0 = Instant::now();
247 sleep_until(t0).await;
248 assert!(t0.elapsed() >= Duration::from_millis(1));
249
250 let t0 = Instant::now();
251
252 sleep(Duration::from_secs(1)).await;
253 assert!(t0.elapsed() >= Duration::from_secs(1));
254
255 sleep_until(t0 + Duration::from_secs(2)).await;
256 assert!(t0.elapsed() >= Duration::from_secs(2));
257
258 assert!(
259 timeout(Duration::from_secs(2), sleep(Duration::from_secs(1)))
260 .await
261 .is_ok()
262 );
263 assert!(
264 timeout(Duration::from_secs(1), sleep(Duration::from_secs(2)))
265 .await
266 .is_err()
267 );
268 });
269 }
270
271 #[test]
272 fn test_advance() {
273 let runtime = Runtime::new();
274 runtime.block_on(async {
275 let t0 = Instant::now();
276 advance(Duration::from_secs(1));
277 assert!(t0.elapsed() >= Duration::from_secs(1));
278 });
279 }
280}