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