1- pub mod host;
2- use cap_std:: time:: Duration ;
1+ use cap_std:: time:: { Duration , Instant , SystemClock } ;
2+ use cap_std:: { AmbientAuthority , ambient_authority} ;
3+ use cap_time_ext:: { MonotonicClockExt as _, SystemClockExt as _} ;
4+
5+ #[ repr( transparent) ]
6+ pub struct WasiClocksImpl < T > ( pub T ) ;
7+
8+ impl < T : WasiClocksView > WasiClocksView for & mut T {
9+ fn clocks ( & mut self ) -> & WasiClocksCtx {
10+ ( * * self ) . clocks ( )
11+ }
12+ }
13+
14+ impl < T : WasiClocksView > WasiClocksView for WasiClocksImpl < T > {
15+ fn clocks ( & mut self ) -> & WasiClocksCtx {
16+ self . 0 . clocks ( )
17+ }
18+ }
19+
20+ impl WasiClocksView for WasiClocksCtx {
21+ fn clocks ( & mut self ) -> & WasiClocksCtx {
22+ self
23+ }
24+ }
25+
26+ pub trait WasiClocksView : Send {
27+ fn clocks ( & mut self ) -> & WasiClocksCtx ;
28+ }
29+
30+ pub struct WasiClocksCtx {
31+ pub wall_clock : Box < dyn HostWallClock + Send > ,
32+ pub monotonic_clock : Box < dyn HostMonotonicClock + Send > ,
33+ }
34+
35+ impl Default for WasiClocksCtx {
36+ fn default ( ) -> Self {
37+ Self {
38+ wall_clock : wall_clock ( ) ,
39+ monotonic_clock : monotonic_clock ( ) ,
40+ }
41+ }
42+ }
343
444pub trait HostWallClock : Send {
545 fn resolution ( & self ) -> Duration ;
@@ -10,3 +50,84 @@ pub trait HostMonotonicClock: Send {
1050 fn resolution ( & self ) -> u64 ;
1151 fn now ( & self ) -> u64 ;
1252}
53+
54+ pub struct WallClock {
55+ /// The underlying system clock.
56+ clock : cap_std:: time:: SystemClock ,
57+ }
58+
59+ impl Default for WallClock {
60+ fn default ( ) -> Self {
61+ Self :: new ( ambient_authority ( ) )
62+ }
63+ }
64+
65+ impl WallClock {
66+ pub fn new ( ambient_authority : AmbientAuthority ) -> Self {
67+ Self {
68+ clock : cap_std:: time:: SystemClock :: new ( ambient_authority) ,
69+ }
70+ }
71+ }
72+
73+ impl HostWallClock for WallClock {
74+ fn resolution ( & self ) -> Duration {
75+ self . clock . resolution ( )
76+ }
77+
78+ fn now ( & self ) -> Duration {
79+ // WASI defines wall clocks to return "Unix time".
80+ self . clock
81+ . now ( )
82+ . duration_since ( SystemClock :: UNIX_EPOCH )
83+ . unwrap ( )
84+ }
85+ }
86+
87+ pub struct MonotonicClock {
88+ /// The underlying system clock.
89+ clock : cap_std:: time:: MonotonicClock ,
90+
91+ /// The `Instant` this clock was created. All returned times are
92+ /// durations since that time.
93+ initial : Instant ,
94+ }
95+
96+ impl Default for MonotonicClock {
97+ fn default ( ) -> Self {
98+ Self :: new ( ambient_authority ( ) )
99+ }
100+ }
101+
102+ impl MonotonicClock {
103+ pub fn new ( ambient_authority : AmbientAuthority ) -> Self {
104+ let clock = cap_std:: time:: MonotonicClock :: new ( ambient_authority) ;
105+ let initial = clock. now ( ) ;
106+ Self { clock, initial }
107+ }
108+ }
109+
110+ impl HostMonotonicClock for MonotonicClock {
111+ fn resolution ( & self ) -> u64 {
112+ self . clock . resolution ( ) . as_nanos ( ) . try_into ( ) . unwrap ( )
113+ }
114+
115+ fn now ( & self ) -> u64 {
116+ // Unwrap here and in `resolution` above; a `u64` is wide enough to
117+ // hold over 584 years of nanoseconds.
118+ self . clock
119+ . now ( )
120+ . duration_since ( self . initial )
121+ . as_nanos ( )
122+ . try_into ( )
123+ . unwrap ( )
124+ }
125+ }
126+
127+ pub fn monotonic_clock ( ) -> Box < dyn HostMonotonicClock + Send > {
128+ Box :: new ( MonotonicClock :: default ( ) )
129+ }
130+
131+ pub fn wall_clock ( ) -> Box < dyn HostWallClock + Send > {
132+ Box :: new ( WallClock :: default ( ) )
133+ }
0 commit comments