]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/hermit/time.rs
New upstream version 1.40.0+dfsg1
[rustc.git] / src / libstd / sys / hermit / time.rs
1 #![allow(dead_code)]
2
3 use crate::time::Duration;
4 use crate::cmp::Ordering;
5 use crate::convert::TryInto;
6 use core::hash::{Hash, Hasher};
7 use crate::sys::hermit::abi;
8 use crate::sys::hermit::abi::{CLOCK_REALTIME, CLOCK_MONOTONIC, NSEC_PER_SEC};
9 use crate::sys::hermit::abi::timespec;
10
11 #[derive(Copy, Clone, Debug)]
12 struct Timespec {
13 t: timespec
14 }
15
16 impl Timespec {
17 const fn zero() -> Timespec {
18 Timespec {
19 t: timespec { tv_sec: 0, tv_nsec: 0 },
20 }
21 }
22
23 fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
24 if self >= other {
25 Ok(if self.t.tv_nsec >= other.t.tv_nsec {
26 Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
27 (self.t.tv_nsec - other.t.tv_nsec) as u32)
28 } else {
29 Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
30 self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
31 other.t.tv_nsec as u32)
32 })
33 } else {
34 match other.sub_timespec(self) {
35 Ok(d) => Err(d),
36 Err(d) => Ok(d),
37 }
38 }
39 }
40
41 fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
42 let mut secs = other
43 .as_secs()
44 .try_into() // <- target type would be `libc::time_t`
45 .ok()
46 .and_then(|secs| self.t.tv_sec.checked_add(secs))?;
47
48 // Nano calculations can't overflow because nanos are <1B which fit
49 // in a u32.
50 let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
51 if nsec >= NSEC_PER_SEC as u32 {
52 nsec -= NSEC_PER_SEC as u32;
53 secs = secs.checked_add(1)?;
54 }
55 Some(Timespec {
56 t: timespec {
57 tv_sec: secs,
58 tv_nsec: nsec as _,
59 },
60 })
61 }
62
63 fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
64 let mut secs = other
65 .as_secs()
66 .try_into() // <- target type would be `libc::time_t`
67 .ok()
68 .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;
69
70 // Similar to above, nanos can't overflow.
71 let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
72 if nsec < 0 {
73 nsec += NSEC_PER_SEC as i32;
74 secs = secs.checked_sub(1)?;
75 }
76 Some(Timespec {
77 t: timespec {
78 tv_sec: secs,
79 tv_nsec: nsec as _,
80 },
81 })
82 }
83 }
84
85 impl PartialEq for Timespec {
86 fn eq(&self, other: &Timespec) -> bool {
87 self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
88 }
89 }
90
91 impl Eq for Timespec {}
92
93 impl PartialOrd for Timespec {
94 fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
95 Some(self.cmp(other))
96 }
97 }
98
99 impl Ord for Timespec {
100 fn cmp(&self, other: &Timespec) -> Ordering {
101 let me = (self.t.tv_sec, self.t.tv_nsec);
102 let other = (other.t.tv_sec, other.t.tv_nsec);
103 me.cmp(&other)
104 }
105 }
106
107 impl Hash for Timespec {
108 fn hash<H : Hasher>(&self, state: &mut H) {
109 self.t.tv_sec.hash(state);
110 self.t.tv_nsec.hash(state);
111 }
112 }
113
114 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
115 pub struct Instant {
116 t: Timespec,
117 }
118
119 impl Instant {
120 pub fn now() -> Instant {
121 let mut time: Timespec = Timespec::zero();
122 let _ = unsafe { abi::clock_gettime(CLOCK_MONOTONIC, &mut time.t as *mut timespec) };
123
124 Instant { t: time }
125 }
126
127 pub const fn zero() -> Instant {
128 Instant { t: Timespec::zero() }
129 }
130
131 pub fn actually_monotonic() -> bool {
132 true
133 }
134
135 pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
136 self.t.sub_timespec(&other.t).ok()
137 }
138
139 pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
140 Some(Instant { t: self.t.checked_add_duration(other)? })
141 }
142
143 pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
144 Some(Instant { t: self.t.checked_sub_duration(other)? })
145 }
146 }
147
148 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
149 pub struct SystemTime {
150 t: Timespec,
151 }
152
153 pub const UNIX_EPOCH: SystemTime = SystemTime {
154 t: Timespec::zero(),
155 };
156
157 impl SystemTime {
158 pub fn now() -> SystemTime {
159 let mut time: Timespec = Timespec::zero();
160 let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, &mut time.t as *mut timespec) };
161
162 SystemTime { t: time }
163 }
164
165 pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
166 self.t.sub_timespec(&other.t)
167 }
168
169 pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
170 Some(SystemTime { t: self.t.checked_add_duration(other)? })
171 }
172
173 pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
174 Some(SystemTime { t: self.t.checked_sub_duration(other)? })
175 }
176 }