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
;
11 #[derive(Copy, Clone, Debug)]
17 const fn zero() -> Timespec
{
19 t
: timespec { tv_sec: 0, tv_nsec: 0 }
,
23 fn sub_timespec(&self, other
: &Timespec
) -> Result
<Duration
, Duration
> {
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)
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)
34 match other
.sub_timespec(self) {
41 fn checked_add_duration(&self, other
: &Duration
) -> Option
<Timespec
> {
44 .try_into() // <- target type would be `libc::time_t`
46 .and_then(|secs
| self.t
.tv_sec
.checked_add(secs
))?
;
48 // Nano calculations can't overflow because nanos are <1B which fit
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)?
;
63 fn checked_sub_duration(&self, other
: &Duration
) -> Option
<Timespec
> {
66 .try_into() // <- target type would be `libc::time_t`
68 .and_then(|secs
| self.t
.tv_sec
.checked_sub(secs
))?
;
70 // Similar to above, nanos can't overflow.
71 let mut nsec
= self.t
.tv_nsec
as i32 - other
.subsec_nanos() as i32;
73 nsec
+= NSEC_PER_SEC
as i32;
74 secs
= secs
.checked_sub(1)?
;
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
91 impl Eq
for Timespec {}
93 impl PartialOrd
for Timespec
{
94 fn partial_cmp(&self, other
: &Timespec
) -> Option
<Ordering
> {
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
);
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
);
114 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
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) }
;
127 pub const fn zero() -> Instant
{
128 Instant { t: Timespec::zero() }
131 pub fn actually_monotonic() -> bool
{
135 pub fn checked_sub_instant(&self, other
: &Instant
) -> Option
<Duration
> {
136 self.t
.sub_timespec(&other
.t
).ok()
139 pub fn checked_add_duration(&self, other
: &Duration
) -> Option
<Instant
> {
140 Some(Instant { t: self.t.checked_add_duration(other)? }
)
143 pub fn checked_sub_duration(&self, other
: &Duration
) -> Option
<Instant
> {
144 Some(Instant { t: self.t.checked_sub_duration(other)? }
)
148 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
149 pub struct SystemTime
{
153 pub const UNIX_EPOCH
: SystemTime
= 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) }
;
162 SystemTime { t: time }
165 pub fn sub_time(&self, other
: &SystemTime
) -> Result
<Duration
, Duration
> {
166 self.t
.sub_timespec(&other
.t
)
169 pub fn checked_add_duration(&self, other
: &Duration
) -> Option
<SystemTime
> {
170 Some(SystemTime { t: self.t.checked_add_duration(other)? }
)
173 pub fn checked_sub_duration(&self, other
: &Duration
) -> Option
<SystemTime
> {
174 Some(SystemTime { t: self.t.checked_sub_duration(other)? }
)