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}