xref: /DragonOS/kernel/src/time/mod.rs (revision fbe6becd6dd3cd72643707e0088f20364ac1b166)
113776c11Slogin use core::{fmt, ops};
213776c11Slogin 
313776c11Slogin use self::timekeep::ktime_get_real_ns;
413776c11Slogin 
536fd0130Shoumkh pub mod clocksource;
636fd0130Shoumkh pub mod jiffies;
7bacd691cSlogin pub mod sleep;
8ab5c8ca4Slogin pub mod syscall;
936fd0130Shoumkh pub mod timeconv;
1001876902SGou Ngai pub mod timekeep;
1136fd0130Shoumkh pub mod timekeeping;
12bacd691cSlogin pub mod timer;
1313776c11Slogin /* Time structures. (Partitially taken from smoltcp)
1413776c11Slogin 
1513776c11Slogin The `time` module contains structures used to represent both
1613776c11Slogin absolute and relative time.
1713776c11Slogin 
1813776c11Slogin  - [Instant] is used to represent absolute time.
1913776c11Slogin  - [Duration] is used to represent relative time.
2013776c11Slogin 
2113776c11Slogin [Instant]: struct.Instant.html
2213776c11Slogin [Duration]: struct.Duration.html
2313776c11Slogin */
2436fd0130Shoumkh #[allow(dead_code)]
2536fd0130Shoumkh pub const MSEC_PER_SEC: u32 = 1000;
2636fd0130Shoumkh #[allow(dead_code)]
2736fd0130Shoumkh pub const USEC_PER_MSEC: u32 = 1000;
2836fd0130Shoumkh #[allow(dead_code)]
2936fd0130Shoumkh pub const NSEC_PER_USEC: u32 = 1000;
3036fd0130Shoumkh #[allow(dead_code)]
3136fd0130Shoumkh pub const NSEC_PER_MSEC: u32 = 1000000;
3236fd0130Shoumkh #[allow(dead_code)]
3336fd0130Shoumkh pub const USEC_PER_SEC: u32 = 1000000;
3436fd0130Shoumkh #[allow(dead_code)]
3536fd0130Shoumkh pub const NSEC_PER_SEC: u32 = 1000000000;
3636fd0130Shoumkh #[allow(dead_code)]
3736fd0130Shoumkh pub const FSEC_PER_SEC: u64 = 1000000000000000;
3813776c11Slogin 
39ab5c8ca4Slogin /// 表示时间的结构体,符合POSIX标准。
40004e86ffSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
41ab5c8ca4Slogin #[repr(C)]
42004e86ffSlogin pub struct TimeSpec {
43004e86ffSlogin     pub tv_sec: i64,
44004e86ffSlogin     pub tv_nsec: i64,
45004e86ffSlogin }
4620e3152eSlogin 
4720e3152eSlogin impl TimeSpec {
4813776c11Slogin     #[allow(dead_code)]
4920e3152eSlogin     pub fn new(sec: i64, nsec: i64) -> TimeSpec {
5020e3152eSlogin         return TimeSpec {
5120e3152eSlogin             tv_sec: sec,
5220e3152eSlogin             tv_nsec: nsec,
5320e3152eSlogin         };
5420e3152eSlogin     }
5520e3152eSlogin }
5613776c11Slogin 
5713776c11Slogin /// A representation of an absolute time value.
5813776c11Slogin ///
5913776c11Slogin /// The `Instant` type is a wrapper around a `i64` value that
6013776c11Slogin /// represents a number of microseconds, monotonically increasing
6113776c11Slogin /// since an arbitrary moment in time, such as system startup.
6213776c11Slogin ///
6313776c11Slogin /// * A value of `0` is inherently arbitrary.
6413776c11Slogin /// * A value less than `0` indicates a time before the starting
6513776c11Slogin ///   point.
6613776c11Slogin #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
6713776c11Slogin #[cfg_attr(feature = "defmt", derive(defmt::Format))]
6813776c11Slogin pub struct Instant {
6913776c11Slogin     micros: i64,
7013776c11Slogin }
7113776c11Slogin 
7213776c11Slogin #[allow(dead_code)]
7313776c11Slogin impl Instant {
7413776c11Slogin     pub const ZERO: Instant = Instant::from_micros_const(0);
7513776c11Slogin 
7613776c11Slogin     /// Create a new `Instant` from a number of microseconds.
7713776c11Slogin     pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
7813776c11Slogin         Instant {
7913776c11Slogin             micros: micros.into(),
8013776c11Slogin         }
8113776c11Slogin     }
8213776c11Slogin 
8313776c11Slogin     pub const fn from_micros_const(micros: i64) -> Instant {
8413776c11Slogin         Instant { micros }
8513776c11Slogin     }
8613776c11Slogin 
8713776c11Slogin     /// Create a new `Instant` from a number of milliseconds.
8813776c11Slogin     pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
8913776c11Slogin         Instant {
9013776c11Slogin             micros: millis.into() * 1000,
9113776c11Slogin         }
9213776c11Slogin     }
9313776c11Slogin 
9413776c11Slogin     /// Create a new `Instant` from a number of milliseconds.
9513776c11Slogin     pub const fn from_millis_const(millis: i64) -> Instant {
9613776c11Slogin         Instant {
9713776c11Slogin             micros: millis * 1000,
9813776c11Slogin         }
9913776c11Slogin     }
10013776c11Slogin 
10113776c11Slogin     /// Create a new `Instant` from a number of seconds.
10213776c11Slogin     pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
10313776c11Slogin         Instant {
10413776c11Slogin             micros: secs.into() * 1000000,
10513776c11Slogin         }
10613776c11Slogin     }
10713776c11Slogin 
10813776c11Slogin     /// Create a new `Instant` from the current time
10913776c11Slogin     pub fn now() -> Instant {
11013776c11Slogin         Self::from_micros(ktime_get_real_ns() / 1000)
11113776c11Slogin     }
11213776c11Slogin 
11313776c11Slogin     /// The fractional number of milliseconds that have passed
11413776c11Slogin     /// since the beginning of time.
11513776c11Slogin     pub const fn millis(&self) -> i64 {
11613776c11Slogin         self.micros % 1000000 / 1000
11713776c11Slogin     }
11813776c11Slogin 
11913776c11Slogin     /// The fractional number of microseconds that have passed
12013776c11Slogin     /// since the beginning of time.
12113776c11Slogin     pub const fn micros(&self) -> i64 {
12213776c11Slogin         self.micros % 1000000
12313776c11Slogin     }
12413776c11Slogin 
12513776c11Slogin     /// The number of whole seconds that have passed since the
12613776c11Slogin     /// beginning of time.
12713776c11Slogin     pub const fn secs(&self) -> i64 {
12813776c11Slogin         self.micros / 1000000
12913776c11Slogin     }
13013776c11Slogin 
13113776c11Slogin     /// The total number of milliseconds that have passed since
13213776c11Slogin     /// the beginning of time.
13313776c11Slogin     pub const fn total_millis(&self) -> i64 {
13413776c11Slogin         self.micros / 1000
13513776c11Slogin     }
13613776c11Slogin     /// The total number of milliseconds that have passed since
13713776c11Slogin     /// the beginning of time.
13813776c11Slogin     pub const fn total_micros(&self) -> i64 {
13913776c11Slogin         self.micros
14013776c11Slogin     }
14113776c11Slogin }
14213776c11Slogin 
14313776c11Slogin impl fmt::Display for Instant {
14413776c11Slogin     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14513776c11Slogin         write!(f, "{}.{:0>3}s", self.secs(), self.millis())
14613776c11Slogin     }
14713776c11Slogin }
14813776c11Slogin 
14913776c11Slogin impl ops::Add<Duration> for Instant {
15013776c11Slogin     type Output = Instant;
15113776c11Slogin 
15213776c11Slogin     fn add(self, rhs: Duration) -> Instant {
15313776c11Slogin         Instant::from_micros(self.micros + rhs.total_micros() as i64)
15413776c11Slogin     }
15513776c11Slogin }
15613776c11Slogin 
15713776c11Slogin impl ops::AddAssign<Duration> for Instant {
15813776c11Slogin     fn add_assign(&mut self, rhs: Duration) {
15913776c11Slogin         self.micros += rhs.total_micros() as i64;
16013776c11Slogin     }
16113776c11Slogin }
16213776c11Slogin 
16313776c11Slogin impl ops::Sub<Duration> for Instant {
16413776c11Slogin     type Output = Instant;
16513776c11Slogin 
16613776c11Slogin     fn sub(self, rhs: Duration) -> Instant {
16713776c11Slogin         Instant::from_micros(self.micros - rhs.total_micros() as i64)
16813776c11Slogin     }
16913776c11Slogin }
17013776c11Slogin 
17113776c11Slogin impl ops::SubAssign<Duration> for Instant {
17213776c11Slogin     fn sub_assign(&mut self, rhs: Duration) {
17313776c11Slogin         self.micros -= rhs.total_micros() as i64;
17413776c11Slogin     }
17513776c11Slogin }
17613776c11Slogin 
17713776c11Slogin impl ops::Sub<Instant> for Instant {
17813776c11Slogin     type Output = Duration;
17913776c11Slogin 
18013776c11Slogin     fn sub(self, rhs: Instant) -> Duration {
18113776c11Slogin         Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
18213776c11Slogin     }
18313776c11Slogin }
18413776c11Slogin 
18513776c11Slogin /// A relative amount of time.
18613776c11Slogin #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
18713776c11Slogin #[cfg_attr(feature = "defmt", derive(defmt::Format))]
18813776c11Slogin pub struct Duration {
18913776c11Slogin     micros: u64,
19013776c11Slogin }
19113776c11Slogin 
19213776c11Slogin impl Duration {
19313776c11Slogin     pub const ZERO: Duration = Duration::from_micros(0);
19413776c11Slogin     /// Create a new `Duration` from a number of microseconds.
19513776c11Slogin     pub const fn from_micros(micros: u64) -> Duration {
19613776c11Slogin         Duration { micros }
19713776c11Slogin     }
19813776c11Slogin 
19913776c11Slogin     /// Create a new `Duration` from a number of milliseconds.
20013776c11Slogin     pub const fn from_millis(millis: u64) -> Duration {
20113776c11Slogin         Duration {
20213776c11Slogin             micros: millis * 1000,
20313776c11Slogin         }
20413776c11Slogin     }
20513776c11Slogin 
20613776c11Slogin     /// Create a new `Instant` from a number of seconds.
20713776c11Slogin     pub const fn from_secs(secs: u64) -> Duration {
20813776c11Slogin         Duration {
20913776c11Slogin             micros: secs * 1000000,
21013776c11Slogin         }
21113776c11Slogin     }
21213776c11Slogin 
21313776c11Slogin     /// The fractional number of milliseconds in this `Duration`.
21413776c11Slogin     pub const fn millis(&self) -> u64 {
21513776c11Slogin         self.micros / 1000 % 1000
21613776c11Slogin     }
21713776c11Slogin 
21813776c11Slogin     /// The fractional number of milliseconds in this `Duration`.
21913776c11Slogin     pub const fn micros(&self) -> u64 {
22013776c11Slogin         self.micros % 1000000
22113776c11Slogin     }
22213776c11Slogin 
22313776c11Slogin     /// The number of whole seconds in this `Duration`.
22413776c11Slogin     pub const fn secs(&self) -> u64 {
22513776c11Slogin         self.micros / 1000000
22613776c11Slogin     }
22713776c11Slogin 
22813776c11Slogin     /// The total number of milliseconds in this `Duration`.
22913776c11Slogin     pub const fn total_millis(&self) -> u64 {
23013776c11Slogin         self.micros / 1000
23113776c11Slogin     }
23213776c11Slogin 
23313776c11Slogin     /// The total number of microseconds in this `Duration`.
23413776c11Slogin     pub const fn total_micros(&self) -> u64 {
23513776c11Slogin         self.micros
23613776c11Slogin     }
23713776c11Slogin }
23813776c11Slogin 
23913776c11Slogin impl fmt::Display for Duration {
24013776c11Slogin     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24113776c11Slogin         write!(f, "{}.{:03}s", self.secs(), self.millis())
24213776c11Slogin     }
24313776c11Slogin }
24413776c11Slogin 
24513776c11Slogin impl ops::Add<Duration> for Duration {
24613776c11Slogin     type Output = Duration;
24713776c11Slogin 
24813776c11Slogin     fn add(self, rhs: Duration) -> Duration {
24913776c11Slogin         Duration::from_micros(self.micros + rhs.total_micros())
25013776c11Slogin     }
25113776c11Slogin }
25213776c11Slogin 
25313776c11Slogin impl ops::AddAssign<Duration> for Duration {
25413776c11Slogin     fn add_assign(&mut self, rhs: Duration) {
25513776c11Slogin         self.micros += rhs.total_micros();
25613776c11Slogin     }
25713776c11Slogin }
25813776c11Slogin 
25913776c11Slogin impl ops::Sub<Duration> for Duration {
26013776c11Slogin     type Output = Duration;
26113776c11Slogin 
26213776c11Slogin     fn sub(self, rhs: Duration) -> Duration {
26313776c11Slogin         Duration::from_micros(
26413776c11Slogin             self.micros
26513776c11Slogin                 .checked_sub(rhs.total_micros())
26613776c11Slogin                 .expect("overflow when subtracting durations"),
26713776c11Slogin         )
26813776c11Slogin     }
26913776c11Slogin }
27013776c11Slogin 
27113776c11Slogin impl ops::SubAssign<Duration> for Duration {
27213776c11Slogin     fn sub_assign(&mut self, rhs: Duration) {
27313776c11Slogin         self.micros = self
27413776c11Slogin             .micros
27513776c11Slogin             .checked_sub(rhs.total_micros())
27613776c11Slogin             .expect("overflow when subtracting durations");
27713776c11Slogin     }
27813776c11Slogin }
27913776c11Slogin 
28013776c11Slogin impl ops::Mul<u32> for Duration {
28113776c11Slogin     type Output = Duration;
28213776c11Slogin 
28313776c11Slogin     fn mul(self, rhs: u32) -> Duration {
28413776c11Slogin         Duration::from_micros(self.micros * rhs as u64)
28513776c11Slogin     }
28613776c11Slogin }
28713776c11Slogin 
28813776c11Slogin impl ops::MulAssign<u32> for Duration {
28913776c11Slogin     fn mul_assign(&mut self, rhs: u32) {
29013776c11Slogin         self.micros *= rhs as u64;
29113776c11Slogin     }
29213776c11Slogin }
29313776c11Slogin 
29413776c11Slogin impl ops::Div<u32> for Duration {
29513776c11Slogin     type Output = Duration;
29613776c11Slogin 
29713776c11Slogin     fn div(self, rhs: u32) -> Duration {
29813776c11Slogin         Duration::from_micros(self.micros / rhs as u64)
29913776c11Slogin     }
30013776c11Slogin }
30113776c11Slogin 
30213776c11Slogin impl ops::DivAssign<u32> for Duration {
30313776c11Slogin     fn div_assign(&mut self, rhs: u32) {
30413776c11Slogin         self.micros /= rhs as u64;
30513776c11Slogin     }
30613776c11Slogin }
30713776c11Slogin 
30813776c11Slogin impl ops::Shl<u32> for Duration {
30913776c11Slogin     type Output = Duration;
31013776c11Slogin 
31113776c11Slogin     fn shl(self, rhs: u32) -> Duration {
31213776c11Slogin         Duration::from_micros(self.micros << rhs)
31313776c11Slogin     }
31413776c11Slogin }
31513776c11Slogin 
31613776c11Slogin impl ops::ShlAssign<u32> for Duration {
31713776c11Slogin     fn shl_assign(&mut self, rhs: u32) {
31813776c11Slogin         self.micros <<= rhs;
31913776c11Slogin     }
32013776c11Slogin }
32113776c11Slogin 
32213776c11Slogin impl ops::Shr<u32> for Duration {
32313776c11Slogin     type Output = Duration;
32413776c11Slogin 
32513776c11Slogin     fn shr(self, rhs: u32) -> Duration {
32613776c11Slogin         Duration::from_micros(self.micros >> rhs)
32713776c11Slogin     }
32813776c11Slogin }
32913776c11Slogin 
33013776c11Slogin impl ops::ShrAssign<u32> for Duration {
33113776c11Slogin     fn shr_assign(&mut self, rhs: u32) {
33213776c11Slogin         self.micros >>= rhs;
33313776c11Slogin     }
33413776c11Slogin }
33513776c11Slogin 
33613776c11Slogin impl From<::core::time::Duration> for Duration {
33713776c11Slogin     fn from(other: ::core::time::Duration) -> Duration {
33813776c11Slogin         Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
33913776c11Slogin     }
34013776c11Slogin }
34113776c11Slogin 
34213776c11Slogin impl From<Duration> for ::core::time::Duration {
34313776c11Slogin     fn from(val: Duration) -> Self {
34413776c11Slogin         ::core::time::Duration::from_micros(val.total_micros())
34513776c11Slogin     }
34613776c11Slogin }
34713776c11Slogin 
34813776c11Slogin /// 支持与smoltcp的时间转换
34913776c11Slogin impl From<smoltcp::time::Instant> for Instant {
35013776c11Slogin     fn from(val: smoltcp::time::Instant) -> Self {
35113776c11Slogin         Instant::from_micros(val.micros())
35213776c11Slogin     }
35313776c11Slogin }
35413776c11Slogin 
35513776c11Slogin impl Into<smoltcp::time::Instant> for Instant {
35613776c11Slogin     fn into(self) -> smoltcp::time::Instant {
35713776c11Slogin         smoltcp::time::Instant::from_millis(self.millis())
35813776c11Slogin     }
35913776c11Slogin }
36013776c11Slogin 
36113776c11Slogin /// 支持与smoltcp的时间转换
36213776c11Slogin impl From<smoltcp::time::Duration> for Duration {
36313776c11Slogin     fn from(val: smoltcp::time::Duration) -> Self {
36413776c11Slogin         Duration::from_micros(val.micros())
36513776c11Slogin     }
36613776c11Slogin }
36713776c11Slogin 
36813776c11Slogin impl Into<smoltcp::time::Duration> for Duration {
36913776c11Slogin     fn into(self) -> smoltcp::time::Duration {
37013776c11Slogin         smoltcp::time::Duration::from_millis(self.millis())
37113776c11Slogin     }
37213776c11Slogin }
373*fbe6becdSLoGin 
374*fbe6becdSLoGin pub trait TimeArch {
375*fbe6becdSLoGin     /// Get CPU cycles (Read from register)
376*fbe6becdSLoGin     fn get_cycles() -> usize;
377*fbe6becdSLoGin }
378