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::SteadyTime;
13 #[cfg(any(target_os = "macos", target_os = "ios"))]
18 use sync::{Once, ONCE_INIT};
20 pub struct SteadyTime {
25 pub fn mach_absolute_time() -> u64;
26 pub fn mach_timebase_info(info: *mut libc::mach_timebase_info) -> libc::c_int;
30 pub fn now() -> SteadyTime {
32 t: unsafe { mach_absolute_time() },
36 pub fn ns(&self) -> u64 {
38 self.t * info.numer as u64 / info.denom as u64
42 fn info() -> &'static libc::mach_timebase_info {
43 static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
47 static ONCE: Once = ONCE_INIT;
51 mach_timebase_info(&mut INFO);
57 impl<'a> Sub for &'a SteadyTime {
58 type Output = Duration;
60 fn sub(self, other: &SteadyTime) -> Duration {
62 let diff = self.t as i64 - other.t as i64;
63 Duration::nanoseconds(diff * info.numer as i64 / info.denom as i64)
68 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
74 const NSEC_PER_SEC: i64 = 1_000_000_000;
76 pub struct SteadyTime {
80 // Apparently android provides this in some other library?
81 // Bitrig's RT extensions are in the C library, not a separate librt
82 // OpenBSD provide it via libc
83 #[cfg(not(any(target_os = "android",
85 target_os = "openbsd",
86 target_env = "musl")))]
91 fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
95 pub fn now() -> SteadyTime {
96 let mut t = SteadyTime {
103 assert_eq!(0, clock_gettime(libc::CLOCK_MONOTONIC, &mut t.t));
108 pub fn ns(&self) -> u64 {
109 self.t.tv_sec as u64 * NSEC_PER_SEC as u64 + self.t.tv_nsec as u64
113 impl<'a> Sub for &'a SteadyTime {
114 type Output = Duration;
116 fn sub(self, other: &SteadyTime) -> Duration {
117 if self.t.tv_nsec >= other.t.tv_nsec {
118 Duration::seconds(self.t.tv_sec as i64 - other.t.tv_sec as i64) +
119 Duration::nanoseconds(self.t.tv_nsec as i64 - other.t.tv_nsec as i64)
121 Duration::seconds(self.t.tv_sec as i64 - 1 - other.t.tv_sec as i64) +
122 Duration::nanoseconds(self.t.tv_nsec as i64 + NSEC_PER_SEC -
123 other.t.tv_nsec as i64)