about summary refs log tree commit diff
path: root/src/libstd/time
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-11-10 12:27:56 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-11-12 09:18:35 -0800
commitfcd05ed99ff0aa6157e427a698ac53dbc450135f (patch)
tree62503d355c71c9daf045c0080912fe06ee2f5441 /src/libstd/time
parente4ead7b034c96b705ec34b8325f5f9f778f1cbb9 (diff)
downloadrust-fcd05ed99ff0aa6157e427a698ac53dbc450135f.tar.gz
rust-fcd05ed99ff0aa6157e427a698ac53dbc450135f.zip
time: Deprecate the library in the distribution
This commit deprecates the entire libtime library in favor of the
externally-provided libtime in the rust-lang organization. Users of the
`libtime` crate as-is today should add this to their Cargo manifests:

    [dependencies.time]
    git = "https://github.com/rust-lang/time"

To implement this transition, a new function `Duration::span` was added to the
`std::time::Duration` time. This function takes a closure and then returns the
duration of time it took that closure to execute. This interface will likely
improve with `FnOnce` unboxed closures as moving in and out will be a little
easier.

Due to the deprecation of the in-tree crate, this is a:

[breaking-change]

cc #18855, some of the conversions in the `src/test/bench` area may have been a
little nicer with that implemented
Diffstat (limited to 'src/libstd/time')
-rw-r--r--src/libstd/time/duration.rs8
-rw-r--r--src/libstd/time/mod.rs73
2 files changed, 81 insertions, 0 deletions
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index c3adae8cff8..c2d4afeb9ad 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -135,6 +135,14 @@ impl Duration {
         Duration { secs: secs, nanos: nanos as i32 }
     }
 
+    /// Runs a closure, returning the duration of time it took to run the
+    /// closure.
+    pub fn span(f: ||) -> Duration {
+        let before = super::precise_time_ns();
+        f();
+        Duration::nanoseconds((before - super::precise_time_ns()) as i64)
+    }
+
     /// Returns the total number of whole weeks in the duration.
     #[inline]
     pub fn num_weeks(&self) -> i64 {
diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs
index 436fa5ebdea..7bc15798a4f 100644
--- a/src/libstd/time/mod.rs
+++ b/src/libstd/time/mod.rs
@@ -10,6 +10,79 @@
 
 //! Temporal quantification.
 
+use libc;
+
 pub use self::duration::Duration;
 
 pub mod duration;
+
+/// Returns the current value of a high-resolution performance counter
+/// in nanoseconds since an unspecified epoch.
+// NB: this is intentionally not public, this is not ready to stabilize its api.
+fn precise_time_ns() -> u64 {
+    return os_precise_time_ns();
+
+    #[cfg(windows)]
+    fn os_precise_time_ns() -> u64 {
+        let mut ticks_per_s = 0;
+        assert_eq!(unsafe {
+            libc::QueryPerformanceFrequency(&mut ticks_per_s)
+        }, 1);
+        let ticks_per_s = if ticks_per_s == 0 {1} else {ticks_per_s};
+        let mut ticks = 0;
+        assert_eq!(unsafe {
+            libc::QueryPerformanceCounter(&mut ticks)
+        }, 1);
+
+        return (ticks as u64 * 1000000000) / (ticks_per_s as u64);
+    }
+
+    #[cfg(any(target_os = "macos", target_os = "ios"))]
+    fn os_precise_time_ns() -> u64 {
+        use sync;
+
+        static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0,
+                                                                                   denom: 0 };
+        static ONCE: sync::Once = sync::ONCE_INIT;
+        unsafe {
+            ONCE.doit(|| {
+                imp::mach_timebase_info(&mut TIMEBASE);
+            });
+            let time = imp::mach_absolute_time();
+            time * TIMEBASE.numer as u64 / TIMEBASE.denom as u64
+        }
+    }
+
+    #[cfg(not(any(windows, target_os = "macos", target_os = "ios")))]
+    fn os_precise_time_ns() -> u64 {
+        let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
+        unsafe {
+            imp::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
+        }
+        return (ts.tv_sec as u64) * 1000000000 + (ts.tv_nsec as u64)
+    }
+}
+
+#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios")))]
+mod imp {
+    use libc::{c_int, timespec};
+
+    // Apparently android provides this in some other library?
+    #[cfg(not(target_os = "android"))]
+    #[link(name = "rt")]
+    extern {}
+
+    extern {
+        pub fn clock_gettime(clk_id: c_int, tp: *mut timespec) -> c_int;
+    }
+
+}
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+mod imp {
+    use libc::{c_int, mach_timebase_info};
+
+    extern {
+        pub fn mach_absolute_time() -> u64;
+        pub fn mach_timebase_info(info: *mut mach_timebase_info) -> c_int;
+    }
+}