mod.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. use core::{
  2. fmt,
  3. intrinsics::unlikely,
  4. ops::{self, Sub},
  5. };
  6. use crate::arch::CurrentTimeArch;
  7. use crate::time::syscall::PosixTimeval;
  8. use self::timekeeping::getnstimeofday;
  9. pub mod clocksource;
  10. pub mod jiffies;
  11. pub mod sleep;
  12. pub mod syscall;
  13. pub mod tick_common;
  14. pub mod timeconv;
  15. pub mod timekeep;
  16. pub mod timekeeping;
  17. pub mod timer;
  18. /* Time structures. (Partitially taken from smoltcp)
  19. The `time` module contains structures used to represent both
  20. absolute and relative time.
  21. - [Instant] is used to represent absolute time.
  22. - [Duration] is used to represent relative time.
  23. [Instant]: struct.Instant.html
  24. [Duration]: struct.Duration.html
  25. */
  26. #[allow(dead_code)]
  27. pub const MSEC_PER_SEC: u32 = 1000;
  28. #[allow(dead_code)]
  29. pub const USEC_PER_MSEC: u32 = 1000;
  30. #[allow(dead_code)]
  31. pub const NSEC_PER_USEC: u32 = 1000;
  32. #[allow(dead_code)]
  33. pub const NSEC_PER_MSEC: u32 = 1000000;
  34. #[allow(dead_code)]
  35. pub const USEC_PER_SEC: u32 = 1000000;
  36. #[allow(dead_code)]
  37. pub const NSEC_PER_SEC: u32 = 1000000000;
  38. #[allow(dead_code)]
  39. pub const FSEC_PER_SEC: u64 = 1000000000000000;
  40. /// The clock frequency of the i8253/i8254 PIT
  41. pub const PIT_TICK_RATE: u64 = 1193182;
  42. /// 表示时间的结构体,符合POSIX标准。
  43. #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
  44. #[repr(C)]
  45. pub struct PosixTimeSpec {
  46. pub tv_sec: i64,
  47. pub tv_nsec: i64,
  48. }
  49. impl PosixTimeSpec {
  50. #[allow(dead_code)]
  51. pub fn new(sec: i64, nsec: i64) -> PosixTimeSpec {
  52. return PosixTimeSpec {
  53. tv_sec: sec,
  54. tv_nsec: nsec,
  55. };
  56. }
  57. /// 获取当前时间
  58. #[inline(always)]
  59. pub fn now() -> Self {
  60. getnstimeofday()
  61. }
  62. /// 获取当前CPU时间(使用CPU时钟周期计算,会存在回绕问题)
  63. pub fn now_cpu_time() -> 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 PosixTimeSpec::default();
  70. } else {
  71. return Self::from(Duration::from_millis(
  72. CurrentTimeArch::get_cycles() as u64 / khz,
  73. ));
  74. }
  75. }
  76. #[cfg(target_arch = "riscv64")]
  77. {
  78. return PosixTimeSpec::new(0, 0);
  79. }
  80. }
  81. /// 换算成纳秒
  82. pub fn total_nanos(&self) -> i64 {
  83. self.tv_sec * 1000000000 + self.tv_nsec
  84. }
  85. }
  86. impl Sub for PosixTimeSpec {
  87. type Output = Duration;
  88. fn sub(self, rhs: Self) -> Self::Output {
  89. let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0);
  90. let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0);
  91. Duration::from_micros((sec * 1000000 + nsec / 1000) as u64)
  92. }
  93. }
  94. impl From<Duration> for PosixTimeSpec {
  95. fn from(dur: Duration) -> Self {
  96. PosixTimeSpec {
  97. tv_sec: dur.total_micros() as i64 / 1000000,
  98. tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000,
  99. }
  100. }
  101. }
  102. impl From<PosixTimeval> for PosixTimeSpec {
  103. fn from(value: PosixTimeval) -> Self {
  104. PosixTimeSpec {
  105. tv_sec: value.tv_sec,
  106. tv_nsec: value.tv_usec as i64 * 1000,
  107. }
  108. }
  109. }
  110. impl From<PosixTimeSpec> for Duration {
  111. fn from(val: PosixTimeSpec) -> Self {
  112. Duration::from_micros(val.tv_sec as u64 * 1000000 + val.tv_nsec as u64 / 1000)
  113. }
  114. }
  115. /// A representation of an absolute time value.
  116. ///
  117. /// The `Instant` type is a wrapper around a `i64` value that
  118. /// represents a number of microseconds, monotonically increasing
  119. /// since an arbitrary moment in time, such as system startup.
  120. ///
  121. /// * A value of `0` is inherently arbitrary.
  122. /// * A value less than `0` indicates a time before the starting
  123. /// point.
  124. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
  125. pub struct Instant {
  126. micros: i64,
  127. }
  128. #[allow(dead_code)]
  129. impl Instant {
  130. pub const ZERO: Instant = Instant::from_micros_const(0);
  131. /// mktime64 - 将日期转换为秒。
  132. ///
  133. /// ## 参数
  134. ///
  135. /// - year0: 要转换的年份
  136. /// - mon0: 要转换的月份
  137. /// - day: 要转换的天
  138. /// - hour: 要转换的小时
  139. /// - min: 要转换的分钟
  140. /// - sec: 要转换的秒
  141. ///
  142. /// 将公历日期转换为1970-01-01 00:00:00以来的秒数。
  143. /// 假设输入为正常的日期格式,即1980-12-31 23:59:59 => 年份=1980, 月=12, 日=31, 时=23, 分=59, 秒=59。
  144. ///
  145. /// [For the Julian calendar(俄罗斯在1917年之前使用,英国及其殖民地在大西洋1752年之前使用,
  146. /// 其他地方在1582年之前使用,某些社区仍然在使用)省略-year/100+year/400项,
  147. /// 并在结果上加10。]
  148. ///
  149. /// 这个算法最初由高斯(我认为是)发表。
  150. ///
  151. /// 要表示闰秒,可以通过将sec设为60(在ISO 8601允许)来调用此函数。
  152. /// 闰秒与随后的秒一样处理,因为它们在UNIX时间中不存在。
  153. ///
  154. /// 支持将午夜作为当日末尾的24:00:00编码 - 即明天的午夜(在ISO 8601允许)。
  155. ///
  156. /// ## 返回
  157. ///
  158. /// 返回:给定输入日期自1970-01-01 00:00:00以来的秒数
  159. pub fn mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self {
  160. let mut mon: i64 = mon0.into();
  161. let mut year: u64 = year0.into();
  162. let day: u64 = day.into();
  163. let hour: u64 = hour.into();
  164. let min: u64 = min.into();
  165. let sec: u64 = sec.into();
  166. mon -= 2;
  167. /* 1..12 -> 11,12,1..10 */
  168. if mon <= 0 {
  169. /* Puts Feb last since it has leap day */
  170. mon += 12;
  171. year -= 1;
  172. }
  173. let mon = mon as u64;
  174. let secs = ((((year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365
  175. - 719499)
  176. * 24 + hour) /* now have hours - midnight tomorrow handled here */
  177. * 60 + min)/* now have minutes */
  178. * 60
  179. + sec; /* finally seconds */
  180. Self::from_secs(secs as i64)
  181. }
  182. /// Create a new `Instant` from a number of microseconds.
  183. pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
  184. Instant {
  185. micros: micros.into(),
  186. }
  187. }
  188. pub const fn from_micros_const(micros: i64) -> Instant {
  189. Instant { micros }
  190. }
  191. /// Create a new `Instant` from a number of milliseconds.
  192. pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
  193. Instant {
  194. micros: millis.into() * 1000,
  195. }
  196. }
  197. /// Create a new `Instant` from a number of milliseconds.
  198. pub const fn from_millis_const(millis: i64) -> Instant {
  199. Instant {
  200. micros: millis * 1000,
  201. }
  202. }
  203. /// Create a new `Instant` from a number of seconds.
  204. pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
  205. Instant {
  206. micros: secs.into() * 1000000,
  207. }
  208. }
  209. /// Create a new `Instant` from the current time
  210. pub fn now() -> Instant {
  211. let tm = getnstimeofday();
  212. Self::from_micros(tm.tv_sec * 1000000 + tm.tv_nsec / 1000)
  213. }
  214. /// The fractional number of milliseconds that have passed
  215. /// since the beginning of time.
  216. pub const fn millis(&self) -> i64 {
  217. self.micros % 1000000 / 1000
  218. }
  219. /// The fractional number of microseconds that have passed
  220. /// since the beginning of time.
  221. pub const fn micros(&self) -> i64 {
  222. self.micros % 1000000
  223. }
  224. /// The number of whole seconds that have passed since the
  225. /// beginning of time.
  226. pub const fn secs(&self) -> i64 {
  227. self.micros / 1000000
  228. }
  229. /// The total number of milliseconds that have passed since
  230. /// the beginning of time.
  231. pub const fn total_millis(&self) -> i64 {
  232. self.micros / 1000
  233. }
  234. /// The total number of milliseconds that have passed since
  235. /// the beginning of time.
  236. pub const fn total_micros(&self) -> i64 {
  237. self.micros
  238. }
  239. /// Returns the duration between this instant and another one.
  240. ///
  241. /// # Arguments
  242. ///
  243. /// * `earlier` - The earlier instant to calculate the duration since.
  244. ///
  245. /// # Returns
  246. ///
  247. /// An `Option<Duration>` representing the duration between this instant and the earlier one.
  248. /// If the earlier instant is later than this one, it returns `None`.
  249. pub fn duration_since(&self, earlier: Instant) -> Option<Duration> {
  250. if earlier.micros > self.micros {
  251. return None;
  252. }
  253. let micros_diff = self.micros - earlier.micros;
  254. Some(Duration::from_micros(micros_diff as u64))
  255. }
  256. /// Saturating subtraction. Computes `self - other`, returning [`Instant::ZERO`] if the result would be negative.
  257. ///
  258. /// # Arguments
  259. ///
  260. /// * `other` - The `Instant` to subtract from `self`.
  261. ///
  262. /// # Returns
  263. ///
  264. /// The duration between `self` and `other`, or [`Instant::ZERO`] if `other` is later than `self`.
  265. pub fn saturating_sub(self, other: Instant) -> Duration {
  266. if self.micros >= other.micros {
  267. Duration::from_micros((self.micros - other.micros) as u64)
  268. } else {
  269. Duration::ZERO
  270. }
  271. }
  272. }
  273. impl fmt::Display for Instant {
  274. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  275. write!(f, "{}.{:0>3}s", self.secs(), self.millis())
  276. }
  277. }
  278. impl ops::Add<Duration> for Instant {
  279. type Output = Instant;
  280. fn add(self, rhs: Duration) -> Instant {
  281. Instant::from_micros(self.micros + rhs.total_micros() as i64)
  282. }
  283. }
  284. impl ops::AddAssign<Duration> for Instant {
  285. fn add_assign(&mut self, rhs: Duration) {
  286. self.micros += rhs.total_micros() as i64;
  287. }
  288. }
  289. impl ops::Sub<Duration> for Instant {
  290. type Output = Instant;
  291. fn sub(self, rhs: Duration) -> Instant {
  292. Instant::from_micros(self.micros - rhs.total_micros() as i64)
  293. }
  294. }
  295. impl ops::SubAssign<Duration> for Instant {
  296. fn sub_assign(&mut self, rhs: Duration) {
  297. self.micros -= rhs.total_micros() as i64;
  298. }
  299. }
  300. impl ops::Sub<Instant> for Instant {
  301. type Output = Duration;
  302. fn sub(self, rhs: Instant) -> Duration {
  303. Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
  304. }
  305. }
  306. /// A relative amount of time.
  307. #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
  308. pub struct Duration {
  309. micros: u64,
  310. }
  311. impl Duration {
  312. pub const ZERO: Duration = Duration::from_micros(0);
  313. /// Create a new `Duration` from a number of microseconds.
  314. pub const fn from_micros(micros: u64) -> Duration {
  315. Duration { micros }
  316. }
  317. /// Create a new `Duration` from a number of milliseconds.
  318. pub const fn from_millis(millis: u64) -> Duration {
  319. Duration {
  320. micros: millis * 1000,
  321. }
  322. }
  323. /// Create a new `Instant` from a number of seconds.
  324. pub const fn from_secs(secs: u64) -> Duration {
  325. Duration {
  326. micros: secs * 1000000,
  327. }
  328. }
  329. /// The fractional number of milliseconds in this `Duration`.
  330. pub const fn millis(&self) -> u64 {
  331. self.micros / 1000 % 1000
  332. }
  333. /// The fractional number of milliseconds in this `Duration`.
  334. pub const fn micros(&self) -> u64 {
  335. self.micros % 1000000
  336. }
  337. /// The number of whole seconds in this `Duration`.
  338. pub const fn secs(&self) -> u64 {
  339. self.micros / 1000000
  340. }
  341. /// The total number of milliseconds in this `Duration`.
  342. pub const fn total_millis(&self) -> u64 {
  343. self.micros / 1000
  344. }
  345. /// The total number of microseconds in this `Duration`.
  346. pub const fn total_micros(&self) -> u64 {
  347. self.micros
  348. }
  349. }
  350. impl fmt::Display for Duration {
  351. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  352. write!(f, "{}.{:03}s", self.secs(), self.millis())
  353. }
  354. }
  355. impl ops::Add<Duration> for Duration {
  356. type Output = Duration;
  357. fn add(self, rhs: Duration) -> Duration {
  358. Duration::from_micros(self.micros + rhs.total_micros())
  359. }
  360. }
  361. impl ops::AddAssign<Duration> for Duration {
  362. fn add_assign(&mut self, rhs: Duration) {
  363. self.micros += rhs.total_micros();
  364. }
  365. }
  366. impl ops::Sub<Duration> for Duration {
  367. type Output = Duration;
  368. fn sub(self, rhs: Duration) -> Duration {
  369. Duration::from_micros(
  370. self.micros
  371. .checked_sub(rhs.total_micros())
  372. .expect("overflow when subtracting durations"),
  373. )
  374. }
  375. }
  376. impl ops::SubAssign<Duration> for Duration {
  377. fn sub_assign(&mut self, rhs: Duration) {
  378. self.micros = self
  379. .micros
  380. .checked_sub(rhs.total_micros())
  381. .expect("overflow when subtracting durations");
  382. }
  383. }
  384. impl ops::Mul<u32> for Duration {
  385. type Output = Duration;
  386. fn mul(self, rhs: u32) -> Duration {
  387. Duration::from_micros(self.micros * rhs as u64)
  388. }
  389. }
  390. impl ops::MulAssign<u32> for Duration {
  391. fn mul_assign(&mut self, rhs: u32) {
  392. self.micros *= rhs as u64;
  393. }
  394. }
  395. impl ops::Div<u32> for Duration {
  396. type Output = Duration;
  397. fn div(self, rhs: u32) -> Duration {
  398. Duration::from_micros(self.micros / rhs as u64)
  399. }
  400. }
  401. impl ops::DivAssign<u32> for Duration {
  402. fn div_assign(&mut self, rhs: u32) {
  403. self.micros /= rhs as u64;
  404. }
  405. }
  406. impl ops::Shl<u32> for Duration {
  407. type Output = Duration;
  408. fn shl(self, rhs: u32) -> Duration {
  409. Duration::from_micros(self.micros << rhs)
  410. }
  411. }
  412. impl ops::ShlAssign<u32> for Duration {
  413. fn shl_assign(&mut self, rhs: u32) {
  414. self.micros <<= rhs;
  415. }
  416. }
  417. impl ops::Shr<u32> for Duration {
  418. type Output = Duration;
  419. fn shr(self, rhs: u32) -> Duration {
  420. Duration::from_micros(self.micros >> rhs)
  421. }
  422. }
  423. impl ops::ShrAssign<u32> for Duration {
  424. fn shr_assign(&mut self, rhs: u32) {
  425. self.micros >>= rhs;
  426. }
  427. }
  428. impl From<::core::time::Duration> for Duration {
  429. fn from(other: ::core::time::Duration) -> Duration {
  430. Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
  431. }
  432. }
  433. impl From<Duration> for ::core::time::Duration {
  434. fn from(val: Duration) -> Self {
  435. ::core::time::Duration::from_micros(val.total_micros())
  436. }
  437. }
  438. /// 支持与smoltcp的时间转换
  439. impl From<smoltcp::time::Instant> for Instant {
  440. fn from(val: smoltcp::time::Instant) -> Self {
  441. Instant::from_micros(val.micros())
  442. }
  443. }
  444. impl From<Instant> for smoltcp::time::Instant {
  445. fn from(val: Instant) -> Self {
  446. smoltcp::time::Instant::from_millis(val.millis())
  447. }
  448. }
  449. /// 支持与smoltcp的时间转换
  450. impl From<smoltcp::time::Duration> for Duration {
  451. fn from(val: smoltcp::time::Duration) -> Self {
  452. Duration::from_micros(val.micros())
  453. }
  454. }
  455. impl From<Duration> for smoltcp::time::Duration {
  456. fn from(val: Duration) -> Self {
  457. smoltcp::time::Duration::from_millis(val.millis())
  458. }
  459. }
  460. pub trait TimeArch {
  461. /// Get CPU cycles (Read from register)
  462. fn get_cycles() -> usize;
  463. /// Calculate expire cycles
  464. ///
  465. /// # Arguments
  466. ///
  467. /// - `ns` - The time to expire in nanoseconds
  468. ///
  469. /// # Returns
  470. ///
  471. /// The expire cycles
  472. fn cal_expire_cycles(ns: usize) -> usize;
  473. /// 将CPU的时钟周期数转换为纳秒
  474. fn cycles2ns(cycles: usize) -> usize;
  475. }