]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/unix/time.rs
Imported Upstream version 1.5.0+dfsg1
[rustc.git] / src / libstd / sys / unix / time.rs
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
11 pub use self::inner::SteadyTime;
12
13 const NSEC_PER_SEC: u64 = 1_000_000_000;
14
15 #[cfg(any(target_os = "macos", target_os = "ios"))]
16 mod inner {
17 use libc;
18 use time::Duration;
19 use ops::Sub;
20 use sync::Once;
21 use super::NSEC_PER_SEC;
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 }
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 };
45 static ONCE: Once = Once::new();
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 {
59 let info = info();
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)
63 }
64 }
65 }
66
67 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
68 mod inner {
69 use libc;
70 use time::Duration;
71 use ops::Sub;
72 use super::NSEC_PER_SEC;
73
74 pub struct SteadyTime {
75 t: libc::timespec,
76 }
77
78 // Apparently android provides this in some other library?
79 // Bitrig's RT extensions are in the C library, not a separate librt
80 // OpenBSD provide it via libc
81 #[cfg(not(any(target_os = "android",
82 target_os = "bitrig",
83 target_os = "netbsd",
84 target_os = "openbsd",
85 target_env = "musl")))]
86 #[link(name = "rt")]
87 extern {}
88
89
90 extern {
91 #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")]
92 fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
93 }
94
95 impl SteadyTime {
96 pub fn now() -> SteadyTime {
97 let mut t = SteadyTime {
98 t: libc::timespec {
99 tv_sec: 0,
100 tv_nsec: 0,
101 }
102 };
103 unsafe {
104 assert_eq!(0, clock_gettime(libc::CLOCK_MONOTONIC, &mut t.t));
105 }
106 t
107 }
108 }
109
110 impl<'a> Sub for &'a SteadyTime {
111 type Output = Duration;
112
113 fn sub(self, other: &SteadyTime) -> Duration {
114 if self.t.tv_nsec >= other.t.tv_nsec {
115 Duration::new(self.t.tv_sec as u64 - other.t.tv_sec as u64,
116 self.t.tv_nsec as u32 - other.t.tv_nsec as u32)
117 } else {
118 Duration::new(self.t.tv_sec as u64 - 1 - other.t.tv_sec as u64,
119 self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
120 other.t.tv_nsec as u32)
121 }
122 }
123 }
124 }