3 use sys
::{cvt, syscall}
;
6 use core
::hash
::{Hash, Hasher}
;
8 const NSEC_PER_SEC
: u64 = 1_000_000_000;
10 #[derive(Copy, Clone)]
16 fn sub_timespec(&self, other
: &Timespec
) -> Result
<Duration
, Duration
> {
18 Ok(if self.t
.tv_nsec
>= other
.t
.tv_nsec
{
19 Duration
::new((self.t
.tv_sec
- other
.t
.tv_sec
) as u64,
20 (self.t
.tv_nsec
- other
.t
.tv_nsec
) as u32)
22 Duration
::new((self.t
.tv_sec
- 1 - other
.t
.tv_sec
) as u64,
23 self.t
.tv_nsec
as u32 + (NSEC_PER_SEC
as u32) -
24 other
.t
.tv_nsec
as u32)
27 match other
.sub_timespec(self) {
34 fn checked_add_duration(&self, other
: &Duration
) -> Option
<Timespec
> {
37 .try_into() // <- target type would be `i64`
39 .and_then(|secs
| self.t
.tv_sec
.checked_add(secs
))?
;
41 // Nano calculations can't overflow because nanos are <1B which fit
43 let mut nsec
= other
.subsec_nanos() + self.t
.tv_nsec
as u32;
44 if nsec
>= NSEC_PER_SEC
as u32 {
45 nsec
-= NSEC_PER_SEC
as u32;
46 secs
= secs
.checked_add(1)?
;
49 t
: syscall
::TimeSpec
{
56 fn checked_sub_duration(&self, other
: &Duration
) -> Option
<Timespec
> {
59 .try_into() // <- target type would be `i64`
61 .and_then(|secs
| self.t
.tv_sec
.checked_sub(secs
))?
;
63 // Similar to above, nanos can't overflow.
64 let mut nsec
= self.t
.tv_nsec
as i32 - other
.subsec_nanos() as i32;
66 nsec
+= NSEC_PER_SEC
as i32;
67 secs
= secs
.checked_sub(1)?
;
70 t
: syscall
::TimeSpec
{
78 impl PartialEq
for Timespec
{
79 fn eq(&self, other
: &Timespec
) -> bool
{
80 self.t
.tv_sec
== other
.t
.tv_sec
&& self.t
.tv_nsec
== other
.t
.tv_nsec
84 impl Eq
for Timespec {}
86 impl PartialOrd
for Timespec
{
87 fn partial_cmp(&self, other
: &Timespec
) -> Option
<Ordering
> {
92 impl Ord
for Timespec
{
93 fn cmp(&self, other
: &Timespec
) -> Ordering
{
94 let me
= (self.t
.tv_sec
, self.t
.tv_nsec
);
95 let other
= (other
.t
.tv_sec
, other
.t
.tv_nsec
);
100 impl Hash
for Timespec
{
101 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
102 self.t
.tv_sec
.hash(state
);
103 self.t
.tv_nsec
.hash(state
);
107 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
112 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
113 pub struct SystemTime
{
117 pub const UNIX_EPOCH
: SystemTime
= SystemTime
{
119 t
: syscall
::TimeSpec
{
127 pub fn now() -> Instant
{
128 Instant { t: now(syscall::CLOCK_MONOTONIC) }
131 pub const fn zero() -> Instant
{
132 Instant { t: Timespec { t: syscall::TimeSpec { tv_sec: 0, tv_nsec: 0 }
} }
135 pub fn actually_monotonic() -> bool
{
139 pub fn sub_instant(&self, other
: &Instant
) -> Duration
{
140 self.t
.sub_timespec(&other
.t
).unwrap_or_else(|_
| {
141 panic
!("specified instant was later than self")
145 pub fn checked_add_duration(&self, other
: &Duration
) -> Option
<Instant
> {
146 Some(Instant { t: self.t.checked_add_duration(other)? }
)
149 pub fn checked_sub_duration(&self, other
: &Duration
) -> Option
<Instant
> {
150 Some(Instant { t: self.t.checked_sub_duration(other)? }
)
154 impl fmt
::Debug
for Instant
{
155 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
156 f
.debug_struct("Instant")
157 .field("tv_sec", &self.t
.t
.tv_sec
)
158 .field("tv_nsec", &self.t
.t
.tv_nsec
)
164 pub fn now() -> SystemTime
{
165 SystemTime { t: now(syscall::CLOCK_REALTIME) }
168 pub fn sub_time(&self, other
: &SystemTime
)
169 -> Result
<Duration
, Duration
> {
170 self.t
.sub_timespec(&other
.t
)
173 pub fn checked_add_duration(&self, other
: &Duration
) -> Option
<SystemTime
> {
174 Some(SystemTime { t: self.t.checked_add_duration(other)? }
)
177 pub fn checked_sub_duration(&self, other
: &Duration
) -> Option
<SystemTime
> {
178 Some(SystemTime { t: self.t.checked_sub_duration(other)? }
)
182 impl From
<syscall
::TimeSpec
> for SystemTime
{
183 fn from(t
: syscall
::TimeSpec
) -> SystemTime
{
184 SystemTime { t: Timespec { t }
}
188 impl fmt
::Debug
for SystemTime
{
189 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
190 f
.debug_struct("SystemTime")
191 .field("tv_sec", &self.t
.t
.tv_sec
)
192 .field("tv_nsec", &self.t
.t
.tv_nsec
)
197 pub type clock_t
= usize;
199 fn now(clock
: clock_t
) -> Timespec
{
200 let mut t
= Timespec
{
201 t
: syscall
::TimeSpec
{
206 cvt(syscall
::clock_gettime(clock
, &mut t
.t
)).unwrap();