fuchsia_async/runtime/fuchsia/executor/
time.rs1use super::common::EHandle;
6use crate::runtime::DurationExt;
7
8use std::ops;
9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
17#[repr(transparent)]
18pub struct MonotonicInstant(zx::MonotonicInstant);
19
20pub use zx::MonotonicDuration;
21
22impl MonotonicInstant {
23 pub fn now() -> Self {
27 EHandle::local().inner().now()
28 }
29
30 pub fn after(duration: zx::MonotonicDuration) -> Self {
36 Self::now() + duration
37 }
38
39 pub const fn from_zx(t: zx::MonotonicInstant) -> Self {
41 MonotonicInstant(t)
42 }
43
44 pub const fn into_zx(self) -> zx::MonotonicInstant {
46 self.0
47 }
48
49 pub const fn from_nanos(nanos: i64) -> Self {
51 Self::from_zx(zx::MonotonicInstant::from_nanos(nanos))
52 }
53
54 pub const fn into_nanos(self) -> i64 {
56 self.0.into_nanos()
57 }
58
59 pub const INFINITE: MonotonicInstant = MonotonicInstant(zx::MonotonicInstant::INFINITE);
61
62 pub const INFINITE_PAST: MonotonicInstant =
64 MonotonicInstant(zx::MonotonicInstant::INFINITE_PAST);
65
66 pub const ZERO: MonotonicInstant = MonotonicInstant(zx::MonotonicInstant::ZERO);
68}
69
70impl From<zx::MonotonicInstant> for MonotonicInstant {
71 fn from(t: zx::MonotonicInstant) -> MonotonicInstant {
72 MonotonicInstant(t)
73 }
74}
75
76impl From<MonotonicInstant> for zx::MonotonicInstant {
77 fn from(t: MonotonicInstant) -> zx::MonotonicInstant {
78 t.0
79 }
80}
81
82impl ops::Add<zx::MonotonicDuration> for MonotonicInstant {
83 type Output = MonotonicInstant;
84 fn add(self, d: zx::MonotonicDuration) -> MonotonicInstant {
85 MonotonicInstant(self.0 + d)
86 }
87}
88
89impl ops::Add<MonotonicInstant> for zx::MonotonicDuration {
90 type Output = MonotonicInstant;
91 fn add(self, t: MonotonicInstant) -> MonotonicInstant {
92 MonotonicInstant(self + t.0)
93 }
94}
95
96impl ops::Sub<zx::MonotonicDuration> for MonotonicInstant {
97 type Output = MonotonicInstant;
98 fn sub(self, d: zx::MonotonicDuration) -> MonotonicInstant {
99 MonotonicInstant(self.0 - d)
100 }
101}
102
103impl ops::Sub<MonotonicInstant> for MonotonicInstant {
104 type Output = zx::MonotonicDuration;
105 fn sub(self, t: MonotonicInstant) -> zx::MonotonicDuration {
106 self.0 - t.0
107 }
108}
109
110impl ops::AddAssign<zx::MonotonicDuration> for MonotonicInstant {
111 fn add_assign(&mut self, d: zx::MonotonicDuration) {
112 self.0.add_assign(d)
113 }
114}
115
116impl ops::SubAssign<zx::MonotonicDuration> for MonotonicInstant {
117 fn sub_assign(&mut self, d: zx::MonotonicDuration) {
118 self.0.sub_assign(d)
119 }
120}
121
122impl DurationExt for zx::MonotonicDuration {
123 fn after_now(self) -> MonotonicInstant {
124 MonotonicInstant::after(self)
125 }
126}
127
128#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
135#[repr(transparent)]
136pub struct BootInstant(zx::BootInstant);
137
138impl BootInstant {
139 pub fn now() -> Self {
142 EHandle::local().inner().boot_now()
143 }
144
145 pub fn after(duration: zx::BootDuration) -> Self {
149 Self::now() + duration
150 }
151
152 pub const fn from_zx(t: zx::BootInstant) -> Self {
154 BootInstant(t)
155 }
156
157 pub const fn into_zx(self) -> zx::BootInstant {
159 self.0
160 }
161
162 pub const fn from_nanos(nanos: i64) -> Self {
164 Self::from_zx(zx::BootInstant::from_nanos(nanos))
165 }
166
167 pub const fn into_nanos(self) -> i64 {
169 self.0.into_nanos()
170 }
171
172 pub const INFINITE: BootInstant = BootInstant(zx::BootInstant::INFINITE);
174
175 pub const INFINITE_PAST: BootInstant = BootInstant(zx::BootInstant::INFINITE_PAST);
177}
178
179impl From<zx::BootInstant> for BootInstant {
180 fn from(t: zx::BootInstant) -> BootInstant {
181 BootInstant(t)
182 }
183}
184
185impl From<BootInstant> for zx::BootInstant {
186 fn from(t: BootInstant) -> zx::BootInstant {
187 t.0
188 }
189}
190
191impl ops::Add<zx::BootDuration> for BootInstant {
192 type Output = BootInstant;
193 fn add(self, d: zx::BootDuration) -> BootInstant {
194 BootInstant(self.0 + d)
195 }
196}
197
198impl ops::Add<BootInstant> for zx::BootDuration {
199 type Output = BootInstant;
200 fn add(self, t: BootInstant) -> BootInstant {
201 BootInstant(self + t.0)
202 }
203}
204
205impl ops::Sub<zx::BootDuration> for BootInstant {
206 type Output = BootInstant;
207 fn sub(self, d: zx::BootDuration) -> BootInstant {
208 BootInstant(self.0 - d)
209 }
210}
211
212impl ops::Sub<BootInstant> for BootInstant {
213 type Output = zx::BootDuration;
214 fn sub(self, t: BootInstant) -> zx::BootDuration {
215 self.0 - t.0
216 }
217}
218
219impl ops::AddAssign<zx::BootDuration> for BootInstant {
220 fn add_assign(&mut self, d: zx::BootDuration) {
221 self.0.add_assign(d)
222 }
223}
224
225impl ops::SubAssign<zx::BootDuration> for BootInstant {
226 fn sub_assign(&mut self, d: zx::BootDuration) {
227 self.0.sub_assign(d)
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use super::*;
234
235 fn time_operations_param(
236 zxt1: zx::MonotonicInstant,
237 zxt2: zx::MonotonicInstant,
238 d: zx::MonotonicDuration,
239 ) {
240 let t1 = MonotonicInstant::from_zx(zxt1);
241 let t2 = MonotonicInstant::from_zx(zxt2);
242 assert_eq!(t1.into_zx(), zxt1);
243
244 assert_eq!(
245 MonotonicInstant::from_zx(zx::MonotonicInstant::INFINITE),
246 MonotonicInstant::INFINITE
247 );
248 assert_eq!(
249 MonotonicInstant::from_zx(zx::MonotonicInstant::INFINITE_PAST),
250 MonotonicInstant::INFINITE_PAST
251 );
252 assert_eq!(zxt1 - zxt2, t1 - t2);
253 assert_eq!(zxt1 + d, (t1 + d).into_zx());
254 assert_eq!(d + zxt1, (d + t1).into_zx());
255 assert_eq!(zxt1 - d, (t1 - d).into_zx());
256
257 let mut zxt = zxt1;
258 let mut t = t1;
259 t += d;
260 zxt += d;
261 assert_eq!(zxt, t.into_zx());
262 t -= d;
263 zxt -= d;
264 assert_eq!(zxt, t.into_zx());
265 }
266
267 #[test]
268 fn time_operations() {
269 time_operations_param(
270 zx::MonotonicInstant::from_nanos(0),
271 zx::MonotonicInstant::from_nanos(1000),
272 zx::MonotonicDuration::from_seconds(12),
273 );
274 time_operations_param(
275 zx::MonotonicInstant::from_nanos(-100000),
276 zx::MonotonicInstant::from_nanos(65324),
277 zx::MonotonicDuration::from_hours(-785),
278 );
279 }
280
281 #[test]
282 fn time_saturating_add() {
283 assert_eq!(
284 MonotonicInstant::from_nanos(10) + zx::MonotonicDuration::from_nanos(30),
285 MonotonicInstant::from_nanos(40)
286 );
287 assert_eq!(
288 MonotonicInstant::from_nanos(10)
289 + zx::MonotonicDuration::from_nanos(MonotonicInstant::INFINITE.into_nanos()),
290 MonotonicInstant::INFINITE
291 );
292 assert_eq!(
293 MonotonicInstant::from_nanos(-10)
294 + zx::MonotonicDuration::from_nanos(MonotonicInstant::INFINITE_PAST.into_nanos()),
295 MonotonicInstant::INFINITE_PAST
296 );
297 }
298}