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