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