]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/unix/time.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / libstd / sys / unix / time.rs
CommitLineData
85aaf69f
SL
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.
4//
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.
10
11pub use self::inner::SteadyTime;
12
d9579d0f
AL
13const NSEC_PER_SEC: u64 = 1_000_000_000;
14
85aaf69f
SL
15#[cfg(any(target_os = "macos", target_os = "ios"))]
16mod inner {
17 use libc;
18 use time::Duration;
19 use ops::Sub;
62682a34 20 use sync::Once;
d9579d0f 21 use super::NSEC_PER_SEC;
85aaf69f
SL
22
23 pub struct SteadyTime {
24 t: u64
25 }
26
27 extern {
28 pub fn mach_absolute_time() -> u64;
29 pub fn mach_timebase_info(info: *mut libc::mach_timebase_info) -> libc::c_int;
30 }
31
32 impl SteadyTime {
33 pub fn now() -> SteadyTime {
34 SteadyTime {
35 t: unsafe { mach_absolute_time() },
36 }
37 }
85aaf69f
SL
38 }
39
40 fn info() -> &'static libc::mach_timebase_info {
41 static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
42 numer: 0,
43 denom: 0,
44 };
62682a34 45 static ONCE: Once = Once::new();
85aaf69f
SL
46
47 unsafe {
48 ONCE.call_once(|| {
49 mach_timebase_info(&mut INFO);
50 });
51 &INFO
52 }
53 }
54
55 impl<'a> Sub for &'a SteadyTime {
56 type Output = Duration;
57
58 fn sub(self, other: &SteadyTime) -> Duration {
c34b1796 59 let info = info();
d9579d0f
AL
60 let diff = self.t as u64 - other.t as u64;
61 let nanos = diff * info.numer as u64 / info.denom as u64;
62 Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
85aaf69f
SL
63 }
64 }
65}
66
67#[cfg(not(any(target_os = "macos", target_os = "ios")))]
68mod inner {
69 use libc;
70 use time::Duration;
71 use ops::Sub;
d9579d0f 72 use super::NSEC_PER_SEC;
85aaf69f
SL
73
74 pub struct SteadyTime {
75 t: libc::timespec,
76 }
77
78 // Apparently android provides this in some other library?
c34b1796 79 // Bitrig's RT extensions are in the C library, not a separate librt
85aaf69f 80 // OpenBSD provide it via libc
c34b1796
AL
81 #[cfg(not(any(target_os = "android",
82 target_os = "bitrig",
c1a9b12d 83 target_os = "netbsd",
d9579d0f
AL
84 target_os = "openbsd",
85 target_env = "musl")))]
85aaf69f
SL
86 #[link(name = "rt")]
87 extern {}
88
89 extern {
90 fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
91 }
92
93 impl SteadyTime {
94 pub fn now() -> SteadyTime {
95 let mut t = SteadyTime {
96 t: libc::timespec {
97 tv_sec: 0,
98 tv_nsec: 0,
99 }
100 };
101 unsafe {
102 assert_eq!(0, clock_gettime(libc::CLOCK_MONOTONIC, &mut t.t));
103 }
104 t
105 }
85aaf69f
SL
106 }
107
108 impl<'a> Sub for &'a SteadyTime {
109 type Output = Duration;
110
111 fn sub(self, other: &SteadyTime) -> Duration {
112 if self.t.tv_nsec >= other.t.tv_nsec {
d9579d0f
AL
113 Duration::new(self.t.tv_sec as u64 - other.t.tv_sec as u64,
114 self.t.tv_nsec as u32 - other.t.tv_nsec as u32)
85aaf69f 115 } else {
d9579d0f
AL
116 Duration::new(self.t.tv_sec as u64 - 1 - other.t.tv_sec as u64,
117 self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
118 other.t.tv_nsec as u32)
85aaf69f
SL
119 }
120 }
121 }
122}