xref: /DragonOS/kernel/src/time/mod.rs (revision 8612b6ce7afc903999ccf0b65bd65019484d2fad)
1*8612b6ceSLoGin use core::{
2*8612b6ceSLoGin     fmt,
3*8612b6ceSLoGin     ops::{self, Sub},
4*8612b6ceSLoGin };
513776c11Slogin 
613776c11Slogin use self::timekeep::ktime_get_real_ns;
713776c11Slogin 
836fd0130Shoumkh pub mod clocksource;
936fd0130Shoumkh pub mod jiffies;
10bacd691cSlogin pub mod sleep;
11ab5c8ca4Slogin pub mod syscall;
1236fd0130Shoumkh pub mod timeconv;
1301876902SGou Ngai pub mod timekeep;
1436fd0130Shoumkh pub mod timekeeping;
15bacd691cSlogin pub mod timer;
1613776c11Slogin /* Time structures. (Partitially taken from smoltcp)
1713776c11Slogin 
1813776c11Slogin The `time` module contains structures used to represent both
1913776c11Slogin absolute and relative time.
2013776c11Slogin 
2113776c11Slogin  - [Instant] is used to represent absolute time.
2213776c11Slogin  - [Duration] is used to represent relative time.
2313776c11Slogin 
2413776c11Slogin [Instant]: struct.Instant.html
2513776c11Slogin [Duration]: struct.Duration.html
2613776c11Slogin */
2736fd0130Shoumkh #[allow(dead_code)]
2836fd0130Shoumkh pub const MSEC_PER_SEC: u32 = 1000;
2936fd0130Shoumkh #[allow(dead_code)]
3036fd0130Shoumkh pub const USEC_PER_MSEC: u32 = 1000;
3136fd0130Shoumkh #[allow(dead_code)]
3236fd0130Shoumkh pub const NSEC_PER_USEC: u32 = 1000;
3336fd0130Shoumkh #[allow(dead_code)]
3436fd0130Shoumkh pub const NSEC_PER_MSEC: u32 = 1000000;
3536fd0130Shoumkh #[allow(dead_code)]
3636fd0130Shoumkh pub const USEC_PER_SEC: u32 = 1000000;
3736fd0130Shoumkh #[allow(dead_code)]
3836fd0130Shoumkh pub const NSEC_PER_SEC: u32 = 1000000000;
3936fd0130Shoumkh #[allow(dead_code)]
4036fd0130Shoumkh pub const FSEC_PER_SEC: u64 = 1000000000000000;
4113776c11Slogin 
42ab5c8ca4Slogin /// 表示时间的结构体,符合POSIX标准。
43004e86ffSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
44ab5c8ca4Slogin #[repr(C)]
45004e86ffSlogin pub struct TimeSpec {
46004e86ffSlogin     pub tv_sec: i64,
47004e86ffSlogin     pub tv_nsec: i64,
48004e86ffSlogin }
4920e3152eSlogin 
5020e3152eSlogin impl TimeSpec {
5113776c11Slogin     #[allow(dead_code)]
5220e3152eSlogin     pub fn new(sec: i64, nsec: i64) -> TimeSpec {
5320e3152eSlogin         return TimeSpec {
5420e3152eSlogin             tv_sec: sec,
5520e3152eSlogin             tv_nsec: nsec,
5620e3152eSlogin         };
5720e3152eSlogin     }
5820e3152eSlogin }
5913776c11Slogin 
60*8612b6ceSLoGin impl Sub for TimeSpec {
61*8612b6ceSLoGin     type Output = Duration;
62*8612b6ceSLoGin     fn sub(self, rhs: Self) -> Self::Output {
63*8612b6ceSLoGin         let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0);
64*8612b6ceSLoGin         let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0);
65*8612b6ceSLoGin         Duration::from_micros((sec * 1000000 + nsec / 1000) as u64)
66*8612b6ceSLoGin     }
67*8612b6ceSLoGin }
68*8612b6ceSLoGin 
69*8612b6ceSLoGin impl From<Duration> for TimeSpec {
70*8612b6ceSLoGin     fn from(dur: Duration) -> Self {
71*8612b6ceSLoGin         TimeSpec {
72*8612b6ceSLoGin             tv_sec: dur.total_micros() as i64 / 1000000,
73*8612b6ceSLoGin             tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000,
74*8612b6ceSLoGin         }
75*8612b6ceSLoGin     }
76*8612b6ceSLoGin }
77*8612b6ceSLoGin 
78*8612b6ceSLoGin impl Into<Duration> for TimeSpec {
79*8612b6ceSLoGin     fn into(self) -> Duration {
80*8612b6ceSLoGin         Duration::from_micros(self.tv_sec as u64 * 1000000 + self.tv_nsec as u64 / 1000)
81*8612b6ceSLoGin     }
82*8612b6ceSLoGin }
83*8612b6ceSLoGin 
8413776c11Slogin /// A representation of an absolute time value.
8513776c11Slogin ///
8613776c11Slogin /// The `Instant` type is a wrapper around a `i64` value that
8713776c11Slogin /// represents a number of microseconds, monotonically increasing
8813776c11Slogin /// since an arbitrary moment in time, such as system startup.
8913776c11Slogin ///
9013776c11Slogin /// * A value of `0` is inherently arbitrary.
9113776c11Slogin /// * A value less than `0` indicates a time before the starting
9213776c11Slogin ///   point.
9313776c11Slogin #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
9413776c11Slogin #[cfg_attr(feature = "defmt", derive(defmt::Format))]
9513776c11Slogin pub struct Instant {
9613776c11Slogin     micros: i64,
9713776c11Slogin }
9813776c11Slogin 
9913776c11Slogin #[allow(dead_code)]
10013776c11Slogin impl Instant {
10113776c11Slogin     pub const ZERO: Instant = Instant::from_micros_const(0);
10213776c11Slogin 
10313776c11Slogin     /// Create a new `Instant` from a number of microseconds.
10413776c11Slogin     pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
10513776c11Slogin         Instant {
10613776c11Slogin             micros: micros.into(),
10713776c11Slogin         }
10813776c11Slogin     }
10913776c11Slogin 
11013776c11Slogin     pub const fn from_micros_const(micros: i64) -> Instant {
11113776c11Slogin         Instant { micros }
11213776c11Slogin     }
11313776c11Slogin 
11413776c11Slogin     /// Create a new `Instant` from a number of milliseconds.
11513776c11Slogin     pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
11613776c11Slogin         Instant {
11713776c11Slogin             micros: millis.into() * 1000,
11813776c11Slogin         }
11913776c11Slogin     }
12013776c11Slogin 
12113776c11Slogin     /// Create a new `Instant` from a number of milliseconds.
12213776c11Slogin     pub const fn from_millis_const(millis: i64) -> Instant {
12313776c11Slogin         Instant {
12413776c11Slogin             micros: millis * 1000,
12513776c11Slogin         }
12613776c11Slogin     }
12713776c11Slogin 
12813776c11Slogin     /// Create a new `Instant` from a number of seconds.
12913776c11Slogin     pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
13013776c11Slogin         Instant {
13113776c11Slogin             micros: secs.into() * 1000000,
13213776c11Slogin         }
13313776c11Slogin     }
13413776c11Slogin 
13513776c11Slogin     /// Create a new `Instant` from the current time
13613776c11Slogin     pub fn now() -> Instant {
13713776c11Slogin         Self::from_micros(ktime_get_real_ns() / 1000)
13813776c11Slogin     }
13913776c11Slogin 
14013776c11Slogin     /// The fractional number of milliseconds that have passed
14113776c11Slogin     /// since the beginning of time.
14213776c11Slogin     pub const fn millis(&self) -> i64 {
14313776c11Slogin         self.micros % 1000000 / 1000
14413776c11Slogin     }
14513776c11Slogin 
14613776c11Slogin     /// The fractional number of microseconds that have passed
14713776c11Slogin     /// since the beginning of time.
14813776c11Slogin     pub const fn micros(&self) -> i64 {
14913776c11Slogin         self.micros % 1000000
15013776c11Slogin     }
15113776c11Slogin 
15213776c11Slogin     /// The number of whole seconds that have passed since the
15313776c11Slogin     /// beginning of time.
15413776c11Slogin     pub const fn secs(&self) -> i64 {
15513776c11Slogin         self.micros / 1000000
15613776c11Slogin     }
15713776c11Slogin 
15813776c11Slogin     /// The total number of milliseconds that have passed since
15913776c11Slogin     /// the beginning of time.
16013776c11Slogin     pub const fn total_millis(&self) -> i64 {
16113776c11Slogin         self.micros / 1000
16213776c11Slogin     }
16313776c11Slogin     /// The total number of milliseconds that have passed since
16413776c11Slogin     /// the beginning of time.
16513776c11Slogin     pub const fn total_micros(&self) -> i64 {
16613776c11Slogin         self.micros
16713776c11Slogin     }
16813776c11Slogin }
16913776c11Slogin 
17013776c11Slogin impl fmt::Display for Instant {
17113776c11Slogin     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17213776c11Slogin         write!(f, "{}.{:0>3}s", self.secs(), self.millis())
17313776c11Slogin     }
17413776c11Slogin }
17513776c11Slogin 
17613776c11Slogin impl ops::Add<Duration> for Instant {
17713776c11Slogin     type Output = Instant;
17813776c11Slogin 
17913776c11Slogin     fn add(self, rhs: Duration) -> Instant {
18013776c11Slogin         Instant::from_micros(self.micros + rhs.total_micros() as i64)
18113776c11Slogin     }
18213776c11Slogin }
18313776c11Slogin 
18413776c11Slogin impl ops::AddAssign<Duration> for Instant {
18513776c11Slogin     fn add_assign(&mut self, rhs: Duration) {
18613776c11Slogin         self.micros += rhs.total_micros() as i64;
18713776c11Slogin     }
18813776c11Slogin }
18913776c11Slogin 
19013776c11Slogin impl ops::Sub<Duration> for Instant {
19113776c11Slogin     type Output = Instant;
19213776c11Slogin 
19313776c11Slogin     fn sub(self, rhs: Duration) -> Instant {
19413776c11Slogin         Instant::from_micros(self.micros - rhs.total_micros() as i64)
19513776c11Slogin     }
19613776c11Slogin }
19713776c11Slogin 
19813776c11Slogin impl ops::SubAssign<Duration> for Instant {
19913776c11Slogin     fn sub_assign(&mut self, rhs: Duration) {
20013776c11Slogin         self.micros -= rhs.total_micros() as i64;
20113776c11Slogin     }
20213776c11Slogin }
20313776c11Slogin 
20413776c11Slogin impl ops::Sub<Instant> for Instant {
20513776c11Slogin     type Output = Duration;
20613776c11Slogin 
20713776c11Slogin     fn sub(self, rhs: Instant) -> Duration {
20813776c11Slogin         Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
20913776c11Slogin     }
21013776c11Slogin }
21113776c11Slogin 
21213776c11Slogin /// A relative amount of time.
21313776c11Slogin #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
21413776c11Slogin #[cfg_attr(feature = "defmt", derive(defmt::Format))]
21513776c11Slogin pub struct Duration {
21613776c11Slogin     micros: u64,
21713776c11Slogin }
21813776c11Slogin 
21913776c11Slogin impl Duration {
22013776c11Slogin     pub const ZERO: Duration = Duration::from_micros(0);
22113776c11Slogin     /// Create a new `Duration` from a number of microseconds.
22213776c11Slogin     pub const fn from_micros(micros: u64) -> Duration {
22313776c11Slogin         Duration { micros }
22413776c11Slogin     }
22513776c11Slogin 
22613776c11Slogin     /// Create a new `Duration` from a number of milliseconds.
22713776c11Slogin     pub const fn from_millis(millis: u64) -> Duration {
22813776c11Slogin         Duration {
22913776c11Slogin             micros: millis * 1000,
23013776c11Slogin         }
23113776c11Slogin     }
23213776c11Slogin 
23313776c11Slogin     /// Create a new `Instant` from a number of seconds.
23413776c11Slogin     pub const fn from_secs(secs: u64) -> Duration {
23513776c11Slogin         Duration {
23613776c11Slogin             micros: secs * 1000000,
23713776c11Slogin         }
23813776c11Slogin     }
23913776c11Slogin 
24013776c11Slogin     /// The fractional number of milliseconds in this `Duration`.
24113776c11Slogin     pub const fn millis(&self) -> u64 {
24213776c11Slogin         self.micros / 1000 % 1000
24313776c11Slogin     }
24413776c11Slogin 
24513776c11Slogin     /// The fractional number of milliseconds in this `Duration`.
24613776c11Slogin     pub const fn micros(&self) -> u64 {
24713776c11Slogin         self.micros % 1000000
24813776c11Slogin     }
24913776c11Slogin 
25013776c11Slogin     /// The number of whole seconds in this `Duration`.
25113776c11Slogin     pub const fn secs(&self) -> u64 {
25213776c11Slogin         self.micros / 1000000
25313776c11Slogin     }
25413776c11Slogin 
25513776c11Slogin     /// The total number of milliseconds in this `Duration`.
25613776c11Slogin     pub const fn total_millis(&self) -> u64 {
25713776c11Slogin         self.micros / 1000
25813776c11Slogin     }
25913776c11Slogin 
26013776c11Slogin     /// The total number of microseconds in this `Duration`.
26113776c11Slogin     pub const fn total_micros(&self) -> u64 {
26213776c11Slogin         self.micros
26313776c11Slogin     }
26413776c11Slogin }
26513776c11Slogin 
26613776c11Slogin impl fmt::Display for Duration {
26713776c11Slogin     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26813776c11Slogin         write!(f, "{}.{:03}s", self.secs(), self.millis())
26913776c11Slogin     }
27013776c11Slogin }
27113776c11Slogin 
27213776c11Slogin impl ops::Add<Duration> for Duration {
27313776c11Slogin     type Output = Duration;
27413776c11Slogin 
27513776c11Slogin     fn add(self, rhs: Duration) -> Duration {
27613776c11Slogin         Duration::from_micros(self.micros + rhs.total_micros())
27713776c11Slogin     }
27813776c11Slogin }
27913776c11Slogin 
28013776c11Slogin impl ops::AddAssign<Duration> for Duration {
28113776c11Slogin     fn add_assign(&mut self, rhs: Duration) {
28213776c11Slogin         self.micros += rhs.total_micros();
28313776c11Slogin     }
28413776c11Slogin }
28513776c11Slogin 
28613776c11Slogin impl ops::Sub<Duration> for Duration {
28713776c11Slogin     type Output = Duration;
28813776c11Slogin 
28913776c11Slogin     fn sub(self, rhs: Duration) -> Duration {
29013776c11Slogin         Duration::from_micros(
29113776c11Slogin             self.micros
29213776c11Slogin                 .checked_sub(rhs.total_micros())
29313776c11Slogin                 .expect("overflow when subtracting durations"),
29413776c11Slogin         )
29513776c11Slogin     }
29613776c11Slogin }
29713776c11Slogin 
29813776c11Slogin impl ops::SubAssign<Duration> for Duration {
29913776c11Slogin     fn sub_assign(&mut self, rhs: Duration) {
30013776c11Slogin         self.micros = self
30113776c11Slogin             .micros
30213776c11Slogin             .checked_sub(rhs.total_micros())
30313776c11Slogin             .expect("overflow when subtracting durations");
30413776c11Slogin     }
30513776c11Slogin }
30613776c11Slogin 
30713776c11Slogin impl ops::Mul<u32> for Duration {
30813776c11Slogin     type Output = Duration;
30913776c11Slogin 
31013776c11Slogin     fn mul(self, rhs: u32) -> Duration {
31113776c11Slogin         Duration::from_micros(self.micros * rhs as u64)
31213776c11Slogin     }
31313776c11Slogin }
31413776c11Slogin 
31513776c11Slogin impl ops::MulAssign<u32> for Duration {
31613776c11Slogin     fn mul_assign(&mut self, rhs: u32) {
31713776c11Slogin         self.micros *= rhs as u64;
31813776c11Slogin     }
31913776c11Slogin }
32013776c11Slogin 
32113776c11Slogin impl ops::Div<u32> for Duration {
32213776c11Slogin     type Output = Duration;
32313776c11Slogin 
32413776c11Slogin     fn div(self, rhs: u32) -> Duration {
32513776c11Slogin         Duration::from_micros(self.micros / rhs as u64)
32613776c11Slogin     }
32713776c11Slogin }
32813776c11Slogin 
32913776c11Slogin impl ops::DivAssign<u32> for Duration {
33013776c11Slogin     fn div_assign(&mut self, rhs: u32) {
33113776c11Slogin         self.micros /= rhs as u64;
33213776c11Slogin     }
33313776c11Slogin }
33413776c11Slogin 
33513776c11Slogin impl ops::Shl<u32> for Duration {
33613776c11Slogin     type Output = Duration;
33713776c11Slogin 
33813776c11Slogin     fn shl(self, rhs: u32) -> Duration {
33913776c11Slogin         Duration::from_micros(self.micros << rhs)
34013776c11Slogin     }
34113776c11Slogin }
34213776c11Slogin 
34313776c11Slogin impl ops::ShlAssign<u32> for Duration {
34413776c11Slogin     fn shl_assign(&mut self, rhs: u32) {
34513776c11Slogin         self.micros <<= rhs;
34613776c11Slogin     }
34713776c11Slogin }
34813776c11Slogin 
34913776c11Slogin impl ops::Shr<u32> for Duration {
35013776c11Slogin     type Output = Duration;
35113776c11Slogin 
35213776c11Slogin     fn shr(self, rhs: u32) -> Duration {
35313776c11Slogin         Duration::from_micros(self.micros >> rhs)
35413776c11Slogin     }
35513776c11Slogin }
35613776c11Slogin 
35713776c11Slogin impl ops::ShrAssign<u32> for Duration {
35813776c11Slogin     fn shr_assign(&mut self, rhs: u32) {
35913776c11Slogin         self.micros >>= rhs;
36013776c11Slogin     }
36113776c11Slogin }
36213776c11Slogin 
36313776c11Slogin impl From<::core::time::Duration> for Duration {
36413776c11Slogin     fn from(other: ::core::time::Duration) -> Duration {
36513776c11Slogin         Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
36613776c11Slogin     }
36713776c11Slogin }
36813776c11Slogin 
36913776c11Slogin impl From<Duration> for ::core::time::Duration {
37013776c11Slogin     fn from(val: Duration) -> Self {
37113776c11Slogin         ::core::time::Duration::from_micros(val.total_micros())
37213776c11Slogin     }
37313776c11Slogin }
37413776c11Slogin 
37513776c11Slogin /// 支持与smoltcp的时间转换
37613776c11Slogin impl From<smoltcp::time::Instant> for Instant {
37713776c11Slogin     fn from(val: smoltcp::time::Instant) -> Self {
37813776c11Slogin         Instant::from_micros(val.micros())
37913776c11Slogin     }
38013776c11Slogin }
38113776c11Slogin 
38213776c11Slogin impl Into<smoltcp::time::Instant> for Instant {
38313776c11Slogin     fn into(self) -> smoltcp::time::Instant {
38413776c11Slogin         smoltcp::time::Instant::from_millis(self.millis())
38513776c11Slogin     }
38613776c11Slogin }
38713776c11Slogin 
38813776c11Slogin /// 支持与smoltcp的时间转换
38913776c11Slogin impl From<smoltcp::time::Duration> for Duration {
39013776c11Slogin     fn from(val: smoltcp::time::Duration) -> Self {
39113776c11Slogin         Duration::from_micros(val.micros())
39213776c11Slogin     }
39313776c11Slogin }
39413776c11Slogin 
39513776c11Slogin impl Into<smoltcp::time::Duration> for Duration {
39613776c11Slogin     fn into(self) -> smoltcp::time::Duration {
39713776c11Slogin         smoltcp::time::Duration::from_millis(self.millis())
39813776c11Slogin     }
39913776c11Slogin }
400fbe6becdSLoGin 
401fbe6becdSLoGin pub trait TimeArch {
402fbe6becdSLoGin     /// Get CPU cycles (Read from register)
403fbe6becdSLoGin     fn get_cycles() -> usize;
404fbe6becdSLoGin }
405