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