xref: /DragonOS/kernel/src/time/mod.rs (revision ab5c8ca46db8e7d4793a9791292122b0b9684274)
1 use core::{fmt, ops};
2 
3 use self::timekeep::ktime_get_real_ns;
4 
5 pub mod sleep;
6 pub mod syscall;
7 pub mod timekeep;
8 pub mod timer;
9 
10 /* Time structures. (Partitially taken from smoltcp)
11 
12 The `time` module contains structures used to represent both
13 absolute and relative time.
14 
15  - [Instant] is used to represent absolute time.
16  - [Duration] is used to represent relative time.
17 
18 [Instant]: struct.Instant.html
19 [Duration]: struct.Duration.html
20 */
21 
22 /// 表示时间的结构体,符合POSIX标准。
23 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
24 #[repr(C)]
25 pub struct TimeSpec {
26     pub tv_sec: i64,
27     pub tv_nsec: i64,
28 }
29 
30 impl TimeSpec {
31     #[allow(dead_code)]
32     pub fn new(sec: i64, nsec: i64) -> TimeSpec {
33         return TimeSpec {
34             tv_sec: sec,
35             tv_nsec: nsec,
36         };
37     }
38 }
39 
40 /// A representation of an absolute time value.
41 ///
42 /// The `Instant` type is a wrapper around a `i64` value that
43 /// represents a number of microseconds, monotonically increasing
44 /// since an arbitrary moment in time, such as system startup.
45 ///
46 /// * A value of `0` is inherently arbitrary.
47 /// * A value less than `0` indicates a time before the starting
48 ///   point.
49 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
50 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
51 pub struct Instant {
52     micros: i64,
53 }
54 
55 #[allow(dead_code)]
56 impl Instant {
57     pub const ZERO: Instant = Instant::from_micros_const(0);
58 
59     /// Create a new `Instant` from a number of microseconds.
60     pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
61         Instant {
62             micros: micros.into(),
63         }
64     }
65 
66     pub const fn from_micros_const(micros: i64) -> Instant {
67         Instant { micros }
68     }
69 
70     /// Create a new `Instant` from a number of milliseconds.
71     pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
72         Instant {
73             micros: millis.into() * 1000,
74         }
75     }
76 
77     /// Create a new `Instant` from a number of milliseconds.
78     pub const fn from_millis_const(millis: i64) -> Instant {
79         Instant {
80             micros: millis * 1000,
81         }
82     }
83 
84     /// Create a new `Instant` from a number of seconds.
85     pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
86         Instant {
87             micros: secs.into() * 1000000,
88         }
89     }
90 
91     /// Create a new `Instant` from the current time
92     pub fn now() -> Instant {
93         Self::from_micros(ktime_get_real_ns() / 1000)
94     }
95 
96     /// The fractional number of milliseconds that have passed
97     /// since the beginning of time.
98     pub const fn millis(&self) -> i64 {
99         self.micros % 1000000 / 1000
100     }
101 
102     /// The fractional number of microseconds that have passed
103     /// since the beginning of time.
104     pub const fn micros(&self) -> i64 {
105         self.micros % 1000000
106     }
107 
108     /// The number of whole seconds that have passed since the
109     /// beginning of time.
110     pub const fn secs(&self) -> i64 {
111         self.micros / 1000000
112     }
113 
114     /// The total number of milliseconds that have passed since
115     /// the beginning of time.
116     pub const fn total_millis(&self) -> i64 {
117         self.micros / 1000
118     }
119     /// The total number of milliseconds that have passed since
120     /// the beginning of time.
121     pub const fn total_micros(&self) -> i64 {
122         self.micros
123     }
124 }
125 
126 impl fmt::Display for Instant {
127     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128         write!(f, "{}.{:0>3}s", self.secs(), self.millis())
129     }
130 }
131 
132 impl ops::Add<Duration> for Instant {
133     type Output = Instant;
134 
135     fn add(self, rhs: Duration) -> Instant {
136         Instant::from_micros(self.micros + rhs.total_micros() as i64)
137     }
138 }
139 
140 impl ops::AddAssign<Duration> for Instant {
141     fn add_assign(&mut self, rhs: Duration) {
142         self.micros += rhs.total_micros() as i64;
143     }
144 }
145 
146 impl ops::Sub<Duration> for Instant {
147     type Output = Instant;
148 
149     fn sub(self, rhs: Duration) -> Instant {
150         Instant::from_micros(self.micros - rhs.total_micros() as i64)
151     }
152 }
153 
154 impl ops::SubAssign<Duration> for Instant {
155     fn sub_assign(&mut self, rhs: Duration) {
156         self.micros -= rhs.total_micros() as i64;
157     }
158 }
159 
160 impl ops::Sub<Instant> for Instant {
161     type Output = Duration;
162 
163     fn sub(self, rhs: Instant) -> Duration {
164         Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
165     }
166 }
167 
168 /// A relative amount of time.
169 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
170 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
171 pub struct Duration {
172     micros: u64,
173 }
174 
175 impl Duration {
176     pub const ZERO: Duration = Duration::from_micros(0);
177     /// Create a new `Duration` from a number of microseconds.
178     pub const fn from_micros(micros: u64) -> Duration {
179         Duration { micros }
180     }
181 
182     /// Create a new `Duration` from a number of milliseconds.
183     pub const fn from_millis(millis: u64) -> Duration {
184         Duration {
185             micros: millis * 1000,
186         }
187     }
188 
189     /// Create a new `Instant` from a number of seconds.
190     pub const fn from_secs(secs: u64) -> Duration {
191         Duration {
192             micros: secs * 1000000,
193         }
194     }
195 
196     /// The fractional number of milliseconds in this `Duration`.
197     pub const fn millis(&self) -> u64 {
198         self.micros / 1000 % 1000
199     }
200 
201     /// The fractional number of milliseconds in this `Duration`.
202     pub const fn micros(&self) -> u64 {
203         self.micros % 1000000
204     }
205 
206     /// The number of whole seconds in this `Duration`.
207     pub const fn secs(&self) -> u64 {
208         self.micros / 1000000
209     }
210 
211     /// The total number of milliseconds in this `Duration`.
212     pub const fn total_millis(&self) -> u64 {
213         self.micros / 1000
214     }
215 
216     /// The total number of microseconds in this `Duration`.
217     pub const fn total_micros(&self) -> u64 {
218         self.micros
219     }
220 }
221 
222 impl fmt::Display for Duration {
223     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224         write!(f, "{}.{:03}s", self.secs(), self.millis())
225     }
226 }
227 
228 impl ops::Add<Duration> for Duration {
229     type Output = Duration;
230 
231     fn add(self, rhs: Duration) -> Duration {
232         Duration::from_micros(self.micros + rhs.total_micros())
233     }
234 }
235 
236 impl ops::AddAssign<Duration> for Duration {
237     fn add_assign(&mut self, rhs: Duration) {
238         self.micros += rhs.total_micros();
239     }
240 }
241 
242 impl ops::Sub<Duration> for Duration {
243     type Output = Duration;
244 
245     fn sub(self, rhs: Duration) -> Duration {
246         Duration::from_micros(
247             self.micros
248                 .checked_sub(rhs.total_micros())
249                 .expect("overflow when subtracting durations"),
250         )
251     }
252 }
253 
254 impl ops::SubAssign<Duration> for Duration {
255     fn sub_assign(&mut self, rhs: Duration) {
256         self.micros = self
257             .micros
258             .checked_sub(rhs.total_micros())
259             .expect("overflow when subtracting durations");
260     }
261 }
262 
263 impl ops::Mul<u32> for Duration {
264     type Output = Duration;
265 
266     fn mul(self, rhs: u32) -> Duration {
267         Duration::from_micros(self.micros * rhs as u64)
268     }
269 }
270 
271 impl ops::MulAssign<u32> for Duration {
272     fn mul_assign(&mut self, rhs: u32) {
273         self.micros *= rhs as u64;
274     }
275 }
276 
277 impl ops::Div<u32> for Duration {
278     type Output = Duration;
279 
280     fn div(self, rhs: u32) -> Duration {
281         Duration::from_micros(self.micros / rhs as u64)
282     }
283 }
284 
285 impl ops::DivAssign<u32> for Duration {
286     fn div_assign(&mut self, rhs: u32) {
287         self.micros /= rhs as u64;
288     }
289 }
290 
291 impl ops::Shl<u32> for Duration {
292     type Output = Duration;
293 
294     fn shl(self, rhs: u32) -> Duration {
295         Duration::from_micros(self.micros << rhs)
296     }
297 }
298 
299 impl ops::ShlAssign<u32> for Duration {
300     fn shl_assign(&mut self, rhs: u32) {
301         self.micros <<= rhs;
302     }
303 }
304 
305 impl ops::Shr<u32> for Duration {
306     type Output = Duration;
307 
308     fn shr(self, rhs: u32) -> Duration {
309         Duration::from_micros(self.micros >> rhs)
310     }
311 }
312 
313 impl ops::ShrAssign<u32> for Duration {
314     fn shr_assign(&mut self, rhs: u32) {
315         self.micros >>= rhs;
316     }
317 }
318 
319 impl From<::core::time::Duration> for Duration {
320     fn from(other: ::core::time::Duration) -> Duration {
321         Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
322     }
323 }
324 
325 impl From<Duration> for ::core::time::Duration {
326     fn from(val: Duration) -> Self {
327         ::core::time::Duration::from_micros(val.total_micros())
328     }
329 }
330 
331 /// 支持与smoltcp的时间转换
332 impl From<smoltcp::time::Instant> for Instant {
333     fn from(val: smoltcp::time::Instant) -> Self {
334         Instant::from_micros(val.micros())
335     }
336 }
337 
338 impl Into<smoltcp::time::Instant> for Instant {
339     fn into(self) -> smoltcp::time::Instant {
340         smoltcp::time::Instant::from_millis(self.millis())
341     }
342 }
343 
344 /// 支持与smoltcp的时间转换
345 impl From<smoltcp::time::Duration> for Duration {
346     fn from(val: smoltcp::time::Duration) -> Self {
347         Duration::from_micros(val.micros())
348     }
349 }
350 
351 impl Into<smoltcp::time::Duration> for Duration {
352     fn into(self) -> smoltcp::time::Duration {
353         smoltcp::time::Duration::from_millis(self.millis())
354     }
355 }
356