kernel_api/
time.rs

1#![unstable(feature = "kernel_time", issue = "none")]
2
3use core::ops::{Add, AddAssign, Sub, SubAssign};
4use core::time::Duration;
5
6#[derive(Copy, Clone, Hash, Debug, Ord, PartialOrd, Eq, PartialEq)]
7pub struct Instant {
8	arch_val: u128
9}
10
11impl Instant {
12	fn nanos(&self) -> u128 {
13		Self::arch_to_nanos(self.arch_val)
14	}
15	
16	fn arch_to_nanos(arch_val: u128) -> u128 {
17		let (num, denom) = unsafe { crate::bridge::time::system_time_to_nanos() };
18
19		arch_val * num / denom.get()
20	}
21
22	fn nanos_to_arch(nanos: u128) -> u128 {
23		let (num, denom) = unsafe { crate::bridge::time::system_time_to_nanos() };
24
25		nanos * denom.get() / num
26	}
27	
28	pub fn now() -> Self {
29		let arch_val = unsafe { crate::bridge::time::system_time() };
30		Self {
31			arch_val
32		}
33	}
34
35	pub fn duration_since(&self, earlier: Instant) -> Duration {
36		self.saturating_duration_since(earlier)
37	}
38
39	pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
40		let nanos = self.nanos().checked_sub(earlier.nanos())?;
41		Some(Duration::new(
42			(nanos / 1_000_000_000) as u64,
43			(nanos % 1_000_000_000) as u32
44		))
45	}
46
47	pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
48		let nanos = self.nanos().saturating_sub(earlier.nanos());
49		Duration::new(
50			(nanos / 1_000_000_000) as u64,
51			(nanos % 1_000_000_000) as u32
52		)
53	}
54
55	pub fn elapsed(&self) -> Duration {
56		Self::now() - *self
57	}
58
59	pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
60		let arch_val = self.arch_val.checked_add(Self::nanos_to_arch(duration.as_nanos()))?;
61		Some(Instant { arch_val })
62	}
63
64	pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
65		let arch_val = self.arch_val.checked_sub(Self::nanos_to_arch(duration.as_nanos()))?;
66		Some(Instant { arch_val })
67	}
68	
69	pub fn nanos_since_boot(&self) -> u128 {
70		self.nanos()
71	}
72	
73	pub fn get(&self) -> u128 { self.arch_val }
74}
75
76impl Add<Duration> for Instant {
77	type Output = Instant;
78
79	fn add(self, rhs: Duration) -> Self::Output {
80		Instant { arch_val: self.arch_val + Self::nanos_to_arch(rhs.as_nanos()) }
81	}
82}
83
84impl AddAssign<Duration> for Instant {
85	fn add_assign(&mut self, rhs: Duration) {
86		self.arch_val += Self::nanos_to_arch(rhs.as_nanos());
87	}
88}
89
90impl Sub for Instant {
91	type Output = Duration;
92
93	fn sub(self, rhs: Instant) -> Self::Output {
94		self.duration_since(rhs)
95	}
96}
97
98impl Sub<Duration> for Instant {
99	type Output = Instant;
100
101	fn sub(self, rhs: Duration) -> Self::Output {
102		Instant { arch_val: self.arch_val - Self::nanos_to_arch(rhs.as_nanos()) }
103	}
104}
105
106impl SubAssign<Duration> for Instant {
107	fn sub_assign(&mut self, rhs: Duration) {
108		self.arch_val -= Self::nanos_to_arch(rhs.as_nanos());
109	}
110}