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
67impl From<zx::MonotonicInstant> for MonotonicInstant {
68 fn from(t: zx::MonotonicInstant) -> MonotonicInstant {
69 MonotonicInstant(t)
70 }
71}
72
73impl From<MonotonicInstant> for zx::MonotonicInstant {
74 fn from(t: MonotonicInstant) -> zx::MonotonicInstant {
75 t.0
76 }
77}
78
79impl ops::Add<zx::MonotonicDuration> for MonotonicInstant {
80 type Output = MonotonicInstant;
81 fn add(self, d: zx::MonotonicDuration) -> MonotonicInstant {
82 MonotonicInstant(self.0 + d)
83 }
84}
85
86impl ops::Add<MonotonicInstant> for zx::MonotonicDuration {
87 type Output = MonotonicInstant;
88 fn add(self, t: MonotonicInstant) -> MonotonicInstant {
89 MonotonicInstant(self + t.0)
90 }
91}
92
93impl ops::Sub<zx::MonotonicDuration> for MonotonicInstant {
94 type Output = MonotonicInstant;
95 fn sub(self, d: zx::MonotonicDuration) -> MonotonicInstant {
96 MonotonicInstant(self.0 - d)
97 }
98}
99
100impl ops::Sub<MonotonicInstant> for MonotonicInstant {
101 type Output = zx::MonotonicDuration;
102 fn sub(self, t: MonotonicInstant) -> zx::MonotonicDuration {
103 self.0 - t.0
104 }
105}
106
107impl ops::AddAssign<zx::MonotonicDuration> for MonotonicInstant {
108 fn add_assign(&mut self, d: zx::MonotonicDuration) {
109 self.0.add_assign(d)
110 }
111}
112
113impl ops::SubAssign<zx::MonotonicDuration> for MonotonicInstant {
114 fn sub_assign(&mut self, d: zx::MonotonicDuration) {
115 self.0.sub_assign(d)
116 }
117}
118
119impl DurationExt for zx::MonotonicDuration {
120 fn after_now(self) -> MonotonicInstant {
121 MonotonicInstant::after(self)
122 }
123}
124
125#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
132#[repr(transparent)]
133pub struct BootInstant(zx::BootInstant);
134
135impl BootInstant {
136 pub fn now() -> Self {
139 EHandle::local().inner().boot_now()
140 }
141
142 pub fn after(duration: zx::BootDuration) -> Self {
146 Self::now() + duration
147 }
148
149 pub const fn from_zx(t: zx::BootInstant) -> Self {
151 BootInstant(t)
152 }
153
154 pub const fn into_zx(self) -> zx::BootInstant {
156 self.0
157 }
158
159 pub const fn from_nanos(nanos: i64) -> Self {
161 Self::from_zx(zx::BootInstant::from_nanos(nanos))
162 }
163
164 pub const fn into_nanos(self) -> i64 {
166 self.0.into_nanos()
167 }
168
169 pub const INFINITE: BootInstant = BootInstant(zx::BootInstant::INFINITE);
171
172 pub const INFINITE_PAST: BootInstant = BootInstant(zx::BootInstant::INFINITE_PAST);
174}
175
176impl From<zx::BootInstant> for BootInstant {
177 fn from(t: zx::BootInstant) -> BootInstant {
178 BootInstant(t)
179 }
180}
181
182impl From<BootInstant> for zx::BootInstant {
183 fn from(t: BootInstant) -> zx::BootInstant {
184 t.0
185 }
186}
187
188impl ops::Add<zx::BootDuration> for BootInstant {
189 type Output = BootInstant;
190 fn add(self, d: zx::BootDuration) -> BootInstant {
191 BootInstant(self.0 + d)
192 }
193}
194
195impl ops::Add<BootInstant> for zx::BootDuration {
196 type Output = BootInstant;
197 fn add(self, t: BootInstant) -> BootInstant {
198 BootInstant(self + t.0)
199 }
200}
201
202impl ops::Sub<zx::BootDuration> for BootInstant {
203 type Output = BootInstant;
204 fn sub(self, d: zx::BootDuration) -> BootInstant {
205 BootInstant(self.0 - d)
206 }
207}
208
209impl ops::Sub<BootInstant> for BootInstant {
210 type Output = zx::BootDuration;
211 fn sub(self, t: BootInstant) -> zx::BootDuration {
212 self.0 - t.0
213 }
214}
215
216impl ops::AddAssign<zx::BootDuration> for BootInstant {
217 fn add_assign(&mut self, d: zx::BootDuration) {
218 self.0.add_assign(d)
219 }
220}
221
222impl ops::SubAssign<zx::BootDuration> for BootInstant {
223 fn sub_assign(&mut self, d: zx::BootDuration) {
224 self.0.sub_assign(d)
225 }
226}
227
228#[cfg(test)]
229mod tests {
230 use super::*;
231
232 fn time_operations_param(
233 zxt1: zx::MonotonicInstant,
234 zxt2: zx::MonotonicInstant,
235 d: zx::MonotonicDuration,
236 ) {
237 let t1 = MonotonicInstant::from_zx(zxt1);
238 let t2 = MonotonicInstant::from_zx(zxt2);
239 assert_eq!(t1.into_zx(), zxt1);
240
241 assert_eq!(
242 MonotonicInstant::from_zx(zx::MonotonicInstant::INFINITE),
243 MonotonicInstant::INFINITE
244 );
245 assert_eq!(
246 MonotonicInstant::from_zx(zx::MonotonicInstant::INFINITE_PAST),
247 MonotonicInstant::INFINITE_PAST
248 );
249 assert_eq!(zxt1 - zxt2, t1 - t2);
250 assert_eq!(zxt1 + d, (t1 + d).into_zx());
251 assert_eq!(d + zxt1, (d + t1).into_zx());
252 assert_eq!(zxt1 - d, (t1 - d).into_zx());
253
254 let mut zxt = zxt1;
255 let mut t = t1;
256 t += d;
257 zxt += d;
258 assert_eq!(zxt, t.into_zx());
259 t -= d;
260 zxt -= d;
261 assert_eq!(zxt, t.into_zx());
262 }
263
264 #[test]
265 fn time_operations() {
266 time_operations_param(
267 zx::MonotonicInstant::from_nanos(0),
268 zx::MonotonicInstant::from_nanos(1000),
269 zx::MonotonicDuration::from_seconds(12),
270 );
271 time_operations_param(
272 zx::MonotonicInstant::from_nanos(-100000),
273 zx::MonotonicInstant::from_nanos(65324),
274 zx::MonotonicDuration::from_hours(-785),
275 );
276 }
277
278 #[test]
279 fn time_saturating_add() {
280 assert_eq!(
281 MonotonicInstant::from_nanos(10) + zx::MonotonicDuration::from_nanos(30),
282 MonotonicInstant::from_nanos(40)
283 );
284 assert_eq!(
285 MonotonicInstant::from_nanos(10)
286 + zx::MonotonicDuration::from_nanos(MonotonicInstant::INFINITE.into_nanos()),
287 MonotonicInstant::INFINITE
288 );
289 assert_eq!(
290 MonotonicInstant::from_nanos(-10)
291 + zx::MonotonicDuration::from_nanos(MonotonicInstant::INFINITE_PAST.into_nanos()),
292 MonotonicInstant::INFINITE_PAST
293 );
294 }
295}