1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 pub use self::inner
::{Instant, SystemTime, UNIX_EPOCH}
;
13 const NSEC_PER_SEC
: u64 = 1_000_000_000;
15 #[cfg(any(target_os = "macos", target_os = "ios"))]
20 use super::NSEC_PER_SEC
;
23 use sys_common
::mul_div_u64
;
26 const USEC_PER_SEC
: u64 = NSEC_PER_SEC
/ 1000;
28 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
33 #[derive(Copy, Clone)]
34 pub struct SystemTime
{
38 pub const UNIX_EPOCH
: SystemTime
= SystemTime
{
46 pub fn now() -> Instant
{
47 Instant { t: unsafe { libc::mach_absolute_time() }
}
50 pub fn sub_instant(&self, other
: &Instant
) -> Duration
{
52 let diff
= self.t
.checked_sub(other
.t
)
53 .expect("second instant is later than self");
54 let nanos
= mul_div_u64(diff
, info
.numer
as u64, info
.denom
as u64);
55 Duration
::new(nanos
/ NSEC_PER_SEC
, (nanos
% NSEC_PER_SEC
) as u32)
58 pub fn add_duration(&self, other
: &Duration
) -> Instant
{
60 t
: self.t
.checked_add(dur2intervals(other
))
61 .expect("overflow when adding duration to instant"),
65 pub fn sub_duration(&self, other
: &Duration
) -> Instant
{
67 t
: self.t
.checked_sub(dur2intervals(other
))
68 .expect("overflow when adding duration to instant"),
74 pub fn now() -> SystemTime
{
75 let mut s
= SystemTime
{
82 libc
::gettimeofday(&mut s
.t
, 0 as *mut _
)
87 pub fn sub_time(&self, other
: &SystemTime
)
88 -> Result
<Duration
, Duration
> {
90 Ok(if self.t
.tv_usec
>= other
.t
.tv_usec
{
91 Duration
::new((self.t
.tv_sec
- other
.t
.tv_sec
) as u64,
93 other
.t
.tv_usec
) as u32) * 1000)
95 Duration
::new((self.t
.tv_sec
- 1 - other
.t
.tv_sec
) as u64,
96 (self.t
.tv_usec
as u32 + (USEC_PER_SEC
as u32) -
97 other
.t
.tv_usec
as u32) * 1000)
100 match other
.sub_time(self) {
107 pub fn add_duration(&self, other
: &Duration
) -> SystemTime
{
108 let secs
= (self.t
.tv_sec
as i64).checked_add(other
.as_secs() as i64);
109 let mut secs
= secs
.expect("overflow when adding duration to time");
111 // Nano calculations can't overflow because nanos are <1B which fit
113 let mut usec
= (other
.subsec_nanos() / 1000) + self.t
.tv_usec
as u32;
114 if usec
>= USEC_PER_SEC
as u32 {
115 usec
-= USEC_PER_SEC
as u32;
116 secs
= secs
.checked_add(1).expect("overflow when adding \
121 tv_sec
: secs
as libc
::time_t
,
122 tv_usec
: usec
as libc
::suseconds_t
,
127 pub fn sub_duration(&self, other
: &Duration
) -> SystemTime
{
128 let secs
= (self.t
.tv_sec
as i64).checked_sub(other
.as_secs() as i64);
129 let mut secs
= secs
.expect("overflow when subtracting duration \
132 // Similar to above, nanos can't overflow.
133 let mut usec
= self.t
.tv_usec
as i32 -
134 (other
.subsec_nanos() / 1000) as i32;
136 usec
+= USEC_PER_SEC
as i32;
137 secs
= secs
.checked_sub(1).expect("overflow when subtracting \
138 duration from time");
142 tv_sec
: secs
as libc
::time_t
,
143 tv_usec
: usec
as libc
::suseconds_t
,
149 impl From
<libc
::timeval
> for SystemTime
{
150 fn from(t
: libc
::timeval
) -> SystemTime
{
155 impl PartialEq
for SystemTime
{
156 fn eq(&self, other
: &SystemTime
) -> bool
{
157 self.t
.tv_sec
== other
.t
.tv_sec
&& self.t
.tv_usec
== other
.t
.tv_usec
161 impl Eq
for SystemTime {}
163 impl PartialOrd
for SystemTime
{
164 fn partial_cmp(&self, other
: &SystemTime
) -> Option
<Ordering
> {
165 Some(self.cmp(other
))
169 impl Ord
for SystemTime
{
170 fn cmp(&self, other
: &SystemTime
) -> Ordering
{
171 let me
= (self.t
.tv_sec
, self.t
.tv_usec
);
172 let other
= (other
.t
.tv_sec
, other
.t
.tv_usec
);
177 impl fmt
::Debug
for SystemTime
{
178 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
179 f
.debug_struct("SystemTime")
180 .field("tv_sec", &self.t
.tv_sec
)
181 .field("tv_usec", &self.t
.tv_usec
)
186 fn dur2intervals(dur
: &Duration
) -> u64 {
188 let nanos
= dur
.as_secs().checked_mul(NSEC_PER_SEC
).and_then(|nanos
| {
189 nanos
.checked_add(dur
.subsec_nanos() as u64)
190 }).expect("overflow converting duration to nanoseconds");
191 mul_div_u64(nanos
, info
.denom
as u64, info
.numer
as u64)
194 fn info() -> &'
static libc
::mach_timebase_info
{
195 static mut INFO
: libc
::mach_timebase_info
= libc
::mach_timebase_info
{
199 static ONCE
: Once
= Once
::new();
203 libc
::mach_timebase_info(&mut INFO
);
210 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
215 use super::NSEC_PER_SEC
;
219 #[derive(Copy, Clone)]
224 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
229 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
230 pub struct SystemTime
{
234 pub const UNIX_EPOCH
: SystemTime
= SystemTime
{
244 pub fn now() -> Instant
{
245 Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
248 pub fn sub_instant(&self, other
: &Instant
) -> Duration
{
249 self.t
.sub_timespec(&other
.t
).unwrap_or_else(|_
| {
250 panic
!("other was less than the current instant")
254 pub fn add_duration(&self, other
: &Duration
) -> Instant
{
255 Instant { t: self.t.add_duration(other) }
258 pub fn sub_duration(&self, other
: &Duration
) -> Instant
{
259 Instant { t: self.t.sub_duration(other) }
263 impl fmt
::Debug
for Instant
{
264 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
265 f
.debug_struct("Instant")
266 .field("tv_sec", &self.t
.t
.tv_sec
)
267 .field("tv_nsec", &self.t
.t
.tv_nsec
)
273 pub fn now() -> SystemTime
{
274 SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
277 pub fn sub_time(&self, other
: &SystemTime
)
278 -> Result
<Duration
, Duration
> {
279 self.t
.sub_timespec(&other
.t
)
282 pub fn add_duration(&self, other
: &Duration
) -> SystemTime
{
283 SystemTime { t: self.t.add_duration(other) }
286 pub fn sub_duration(&self, other
: &Duration
) -> SystemTime
{
287 SystemTime { t: self.t.sub_duration(other) }
291 impl From
<libc
::timespec
> for SystemTime
{
292 fn from(t
: libc
::timespec
) -> SystemTime
{
293 SystemTime { t: Timespec { t: t }
}
297 impl fmt
::Debug
for SystemTime
{
298 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
299 f
.debug_struct("SystemTime")
300 .field("tv_sec", &self.t
.t
.tv_sec
)
301 .field("tv_nsec", &self.t
.t
.tv_nsec
)
306 #[cfg(not(target_os = "dragonfly"))]
307 pub type clock_t
= libc
::c_int
;
308 #[cfg(target_os = "dragonfly")]
309 pub type clock_t
= libc
::c_ulong
;
312 pub fn now(clock
: clock_t
) -> Timespec
{
313 let mut t
= Timespec
{
320 libc
::clock_gettime(clock
, &mut t
.t
)
325 fn sub_timespec(&self, other
: &Timespec
) -> Result
<Duration
, Duration
> {
327 Ok(if self.t
.tv_nsec
>= other
.t
.tv_nsec
{
328 Duration
::new((self.t
.tv_sec
- other
.t
.tv_sec
) as u64,
329 (self.t
.tv_nsec
- other
.t
.tv_nsec
) as u32)
331 Duration
::new((self.t
.tv_sec
- 1 - other
.t
.tv_sec
) as u64,
332 self.t
.tv_nsec
as u32 + (NSEC_PER_SEC
as u32) -
333 other
.t
.tv_nsec
as u32)
336 match other
.sub_timespec(self) {
343 fn add_duration(&self, other
: &Duration
) -> Timespec
{
344 let secs
= (self.t
.tv_sec
as i64).checked_add(other
.as_secs() as i64);
345 let mut secs
= secs
.expect("overflow when adding duration to time");
347 // Nano calculations can't overflow because nanos are <1B which fit
349 let mut nsec
= other
.subsec_nanos() + self.t
.tv_nsec
as u32;
350 if nsec
>= NSEC_PER_SEC
as u32 {
351 nsec
-= NSEC_PER_SEC
as u32;
352 secs
= secs
.checked_add(1).expect("overflow when adding \
357 tv_sec
: secs
as libc
::time_t
,
358 tv_nsec
: nsec
as libc
::c_long
,
363 fn sub_duration(&self, other
: &Duration
) -> Timespec
{
364 let secs
= (self.t
.tv_sec
as i64).checked_sub(other
.as_secs() as i64);
365 let mut secs
= secs
.expect("overflow when subtracting duration \
368 // Similar to above, nanos can't overflow.
369 let mut nsec
= self.t
.tv_nsec
as i32 - other
.subsec_nanos() as i32;
371 nsec
+= NSEC_PER_SEC
as i32;
372 secs
= secs
.checked_sub(1).expect("overflow when subtracting \
373 duration from time");
377 tv_sec
: secs
as libc
::time_t
,
378 tv_nsec
: nsec
as libc
::c_long
,
384 impl PartialEq
for Timespec
{
385 fn eq(&self, other
: &Timespec
) -> bool
{
386 self.t
.tv_sec
== other
.t
.tv_sec
&& self.t
.tv_nsec
== other
.t
.tv_nsec
390 impl Eq
for Timespec {}
392 impl PartialOrd
for Timespec
{
393 fn partial_cmp(&self, other
: &Timespec
) -> Option
<Ordering
> {
394 Some(self.cmp(other
))
398 impl Ord
for Timespec
{
399 fn cmp(&self, other
: &Timespec
) -> Ordering
{
400 let me
= (self.t
.tv_sec
, self.t
.tv_nsec
);
401 let other
= (other
.t
.tv_sec
, other
.t
.tv_nsec
);