wasmtime_wasi/clocks/
host.rs

1use super::{HostMonotonicClock, HostWallClock};
2use cap_std::time::{Duration, Instant, SystemClock};
3use cap_std::{ambient_authority, AmbientAuthority};
4use cap_time_ext::{MonotonicClockExt, SystemClockExt};
5
6pub struct WallClock {
7    /// The underlying system clock.
8    clock: cap_std::time::SystemClock,
9}
10
11impl WallClock {
12    pub fn new(ambient_authority: AmbientAuthority) -> Self {
13        Self {
14            clock: cap_std::time::SystemClock::new(ambient_authority),
15        }
16    }
17}
18
19impl HostWallClock for WallClock {
20    fn resolution(&self) -> Duration {
21        self.clock.resolution()
22    }
23
24    fn now(&self) -> Duration {
25        // WASI defines wall clocks to return "Unix time".
26        self.clock
27            .now()
28            .duration_since(SystemClock::UNIX_EPOCH)
29            .unwrap()
30    }
31}
32
33pub struct MonotonicClock {
34    /// The underlying system clock.
35    clock: cap_std::time::MonotonicClock,
36
37    /// The `Instant` this clock was created. All returned times are
38    /// durations since that time.
39    initial: Instant,
40}
41
42impl MonotonicClock {
43    pub fn new(ambient_authority: AmbientAuthority) -> Self {
44        let clock = cap_std::time::MonotonicClock::new(ambient_authority);
45        let initial = clock.now();
46        Self { clock, initial }
47    }
48}
49
50impl HostMonotonicClock for MonotonicClock {
51    fn resolution(&self) -> u64 {
52        self.clock.resolution().as_nanos().try_into().unwrap()
53    }
54
55    fn now(&self) -> u64 {
56        // Unwrap here and in `resolution` above; a `u64` is wide enough to
57        // hold over 584 years of nanoseconds.
58        self.clock
59            .now()
60            .duration_since(self.initial)
61            .as_nanos()
62            .try_into()
63            .unwrap()
64    }
65}
66
67pub fn monotonic_clock() -> Box<dyn HostMonotonicClock + Send> {
68    Box::new(MonotonicClock::new(ambient_authority()))
69}
70
71pub fn wall_clock() -> Box<dyn HostWallClock + Send> {
72    Box::new(WallClock::new(ambient_authority()))
73}