about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-12 22:57:16 +0000
committerbors <bors@rust-lang.org>2014-11-12 22:57:16 +0000
commit5745e419502d753deb3f42026fa35e015bc5d3fb (patch)
tree087cc690130ffb3c4603f755c64cb3b5ed76e095
parent7a86aa83eea27529b1b8855cd4e2c8ce7bf787ef (diff)
parentfcd05ed99ff0aa6157e427a698ac53dbc450135f (diff)
downloadrust-5745e419502d753deb3f42026fa35e015bc5d3fb.tar.gz
rust-5745e419502d753deb3f42026fa35e015bc5d3fb.zip
auto merge of #18858 : alexcrichton/rust/remove-time, r=jakub
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
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/metadata/loader.rs16
-rw-r--r--src/librustc/middle/trans/base.rs18
-rw-r--r--src/librustc/middle/trans/context.rs4
-rw-r--r--src/librustc/util/common.rs18
-rw-r--r--src/librustdoc/lib.rs4
-rw-r--r--src/libstd/time/duration.rs8
-rw-r--r--src/libstd/time/mod.rs73
-rw-r--r--src/libtest/lib.rs71
-rw-r--r--src/libtime/lib.rs3
-rw-r--r--src/test/auxiliary/lint-unused-extern-crate.rs11
-rw-r--r--src/test/bench/core-map.rs8
-rw-r--r--src/test/bench/core-set.rs37
-rw-r--r--src/test/bench/core-std.rs16
-rw-r--r--src/test/bench/msgsend-pipes-shared.rs60
-rw-r--r--src/test/bench/msgsend-pipes.rs74
-rw-r--r--src/test/bench/msgsend-ring-mutex-arcs.rs65
-rw-r--r--src/test/bench/msgsend-ring-rw-arcs.rs65
-rw-r--r--src/test/bench/shootout-pfib.rs12
-rw-r--r--src/test/bench/std-smallintmap.rs23
-rw-r--r--src/test/bench/task-perf-alloc-unwind.rs14
-rw-r--r--src/test/compile-fail/lint-unused-extern-crate.rs8
22 files changed, 336 insertions, 273 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 390648eab2e..7a34c5977d6 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -41,7 +41,6 @@ extern crate rustc_llvm;
 extern crate rustc_back;
 extern crate serialize;
 extern crate rbml;
-extern crate time;
 #[phase(plugin, link)] extern crate log;
 #[phase(plugin, link)] extern crate syntax;
 
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index f46af9088d8..19cc04a20ef 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -228,16 +228,16 @@ use util::fs;
 
 use std::c_str::ToCStr;
 use std::cmp;
+use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::{HashMap, HashSet};
 use std::io::fs::PathExtensions;
 use std::io;
 use std::ptr;
 use std::slice;
 use std::string;
+use std::time::Duration;
 
-use std::collections::{HashMap, HashSet};
-use std::collections::hash_map::{Occupied, Vacant};
 use flate;
-use time;
 
 pub struct CrateMismatch {
     path: Path,
@@ -691,11 +691,13 @@ impl ArchiveMetadata {
 
 // Just a small wrapper to time how long reading metadata takes.
 fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, String> {
-    let start = time::precise_time_ns();
-    let ret = get_metadata_section_imp(is_osx, filename);
+    let mut ret = None;
+    let dur = Duration::span(|| {
+        ret = Some(get_metadata_section_imp(is_osx, filename));
+    });
     info!("reading {} => {}ms", filename.filename_display(),
-           (time::precise_time_ns() - start) / 1000000);
-    return ret;
+          dur.num_milliseconds());
+    return ret.unwrap();;
 }
 
 fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlob, String> {
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 0d8ef560c7d..294b5f96f1c 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -97,8 +97,6 @@ use syntax::visit::Visitor;
 use syntax::visit;
 use syntax::{ast, ast_util, ast_map};
 
-use time;
-
 local_data_key!(task_local_insn_key: RefCell<Vec<&'static str>>)
 
 pub fn with_insn_ctxt(blk: |&[&'static str]|) {
@@ -138,23 +136,16 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
 pub struct StatRecorder<'a, 'tcx: 'a> {
     ccx: &'a CrateContext<'a, 'tcx>,
     name: Option<String>,
-    start: u64,
     istart: uint,
 }
 
 impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
     pub fn new(ccx: &'a CrateContext<'a, 'tcx>, name: String)
                -> StatRecorder<'a, 'tcx> {
-        let start = if ccx.sess().trans_stats() {
-            time::precise_time_ns()
-        } else {
-            0
-        };
         let istart = ccx.stats().n_llvm_insns.get();
         StatRecorder {
             ccx: ccx,
             name: Some(name),
-            start: start,
             istart: istart,
         }
     }
@@ -164,11 +155,8 @@ impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
 impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
     fn drop(&mut self) {
         if self.ccx.sess().trans_stats() {
-            let end = time::precise_time_ns();
-            let elapsed = ((end - self.start) / 1_000_000) as uint;
             let iend = self.ccx.stats().n_llvm_insns.get();
             self.ccx.stats().fn_stats.borrow_mut().push((self.name.take().unwrap(),
-                                                       elapsed,
                                                        iend - self.istart));
             self.ccx.stats().n_fns.set(self.ccx.stats().n_fns.get() + 1);
             // Reset LLVM insn count to avoid compound costs.
@@ -3097,13 +3085,13 @@ pub fn trans_crate<'tcx>(analysis: CrateAnalysis<'tcx>)
         println!("n_inlines: {}", stats.n_inlines.get());
         println!("n_closures: {}", stats.n_closures.get());
         println!("fn stats:");
-        stats.fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| {
+        stats.fn_stats.borrow_mut().sort_by(|&(_, insns_a), &(_, insns_b)| {
             insns_b.cmp(&insns_a)
         });
         for tuple in stats.fn_stats.borrow().iter() {
             match *tuple {
-                (ref name, ms, insns) => {
-                    println!("{} insns, {} ms, {}", insns, ms, *name);
+                (ref name, insns) => {
+                    println!("{} insns, {}", insns, *name);
                 }
             }
         }
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index b659da75222..2ba01aa922a 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -47,8 +47,8 @@ pub struct Stats {
     pub n_closures: Cell<uint>,
     pub n_llvm_insns: Cell<uint>,
     pub llvm_insns: RefCell<FnvHashMap<String, uint>>,
-    // (ident, time-in-ms, llvm-instructions)
-    pub fn_stats: RefCell<Vec<(String, uint, uint)> >,
+    // (ident, llvm-instructions)
+    pub fn_stats: RefCell<Vec<(String, uint)> >,
 }
 
 /// The shared portion of a `CrateContext`.  There is one `SharedCrateContext`
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 9d94f4d2356..b845e507fd3 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -12,14 +12,14 @@
 
 use std::cell::RefCell;
 use std::collections::HashMap;
-use std::hash::{Hash, Hasher};
 use std::fmt::Show;
+use std::hash::{Hash, Hasher};
+use std::time::Duration;
+
 use syntax::ast;
 use syntax::visit;
 use syntax::visit::Visitor;
 
-use time;
-
 pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     local_data_key!(depth: uint);
     if !do_it { return f(u); }
@@ -27,11 +27,15 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     let old = depth.get().map(|d| *d).unwrap_or(0);
     depth.replace(Some(old + 1));
 
-    let start = time::precise_time_s();
-    let rv = f(u);
-    let end = time::precise_time_s();
+    let mut u = Some(u);
+    let mut rv = None;
+    let dur = Duration::span(|| {
+        rv = Some(f(u.take().unwrap()))
+    });
+    let rv = rv.unwrap();
 
-    println!("{}time: {:3.3f} s\t{}", "  ".repeat(old), end - start, what);
+    println!("{}time: {}.{:03} \t{}", "  ".repeat(old),
+             dur.num_seconds(), dur.num_milliseconds(), what);
     depth.replace(Some(old));
 
     rv
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 9b59a258ce1..7343d674972 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -25,7 +25,6 @@ extern crate rustc;
 extern crate serialize;
 extern crate syntax;
 extern crate "test" as testing;
-extern crate time;
 #[phase(plugin, link)] extern crate log;
 
 use std::io;
@@ -238,7 +237,6 @@ pub fn main_args(args: &[String]) -> int {
     };
 
     info!("going to format");
-    let started = time::precise_time_ns();
     match matches.opt_str("w").as_ref().map(|s| s.as_slice()) {
         Some("html") | None => {
             match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc"))) {
@@ -257,8 +255,6 @@ pub fn main_args(args: &[String]) -> int {
             return 1;
         }
     }
-    let ended = time::precise_time_ns();
-    info!("Took {:.03f}s", (ended as f64 - started as f64) / 1e9f64);
 
     return 0;
 }
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;
+    }
+}
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 78f88fa1b58..a57e84b543f 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -39,11 +39,9 @@ extern crate getopts;
 extern crate regex;
 extern crate serialize;
 extern crate term;
-extern crate time;
 
 use std::collections::TreeMap;
 use stats::Stats;
-use time::precise_time_ns;
 use getopts::{OptGroup, optflag, optopt};
 use regex::Regex;
 use serialize::{json, Decodable};
@@ -53,8 +51,8 @@ use term::color::{Color, RED, YELLOW, GREEN, CYAN};
 
 use std::cmp;
 use std::f64;
-use std::fmt;
 use std::fmt::Show;
+use std::fmt;
 use std::from_str::FromStr;
 use std::io::fs::PathExtensions;
 use std::io::stdio::StdWriter;
@@ -63,6 +61,7 @@ use std::io;
 use std::os;
 use std::string::String;
 use std::task::TaskBuilder;
+use std::time::Duration;
 
 // to be used by rustc to compile tests in libtest
 pub mod test {
@@ -175,8 +174,7 @@ impl fmt::Show for TestFn {
 /// call to `iter`.
 pub struct Bencher {
     iterations: u64,
-    ns_start: u64,
-    ns_end: u64,
+    dur: Duration,
     pub bytes: u64,
 }
 
@@ -1272,20 +1270,16 @@ pub fn black_box<T>(dummy: T) {
 impl Bencher {
     /// Callback for benchmark functions to run in their body.
     pub fn iter<T>(&mut self, inner: || -> T) {
-        self.ns_start = precise_time_ns();
-        let k = self.iterations;
-        for _ in range(0u64, k) {
-            black_box(inner());
-        }
-        self.ns_end = precise_time_ns();
+        self.dur = Duration::span(|| {
+            let k = self.iterations;
+            for _ in range(0u64, k) {
+                black_box(inner());
+            }
+        });
     }
 
     pub fn ns_elapsed(&mut self) -> u64 {
-        if self.ns_start == 0 || self.ns_end == 0 {
-            0
-        } else {
-            self.ns_end - self.ns_start
-        }
+        self.dur.num_nanoseconds().unwrap() as u64
     }
 
     pub fn ns_per_iter(&mut self) -> u64 {
@@ -1322,41 +1316,44 @@ impl Bencher {
         // (i.e. larger error bars).
         if n == 0 { n = 1; }
 
-        let mut total_run = 0;
+        let mut total_run = Duration::nanoseconds(0);
         let samples : &mut [f64] = [0.0_f64, ..50];
         loop {
-            let loop_start = precise_time_ns();
+            let mut summ = None;
+            let mut summ5 = None;
 
-            for p in samples.iter_mut() {
-                self.bench_n(n, |x| f(x));
-                *p = self.ns_per_iter() as f64;
-            };
+            let loop_run = Duration::span(|| {
 
-            stats::winsorize(samples, 5.0);
-            let summ = stats::Summary::new(samples);
+                for p in samples.iter_mut() {
+                    self.bench_n(n, |x| f(x));
+                    *p = self.ns_per_iter() as f64;
+                };
 
-            for p in samples.iter_mut() {
-                self.bench_n(5 * n, |x| f(x));
-                *p = self.ns_per_iter() as f64;
-            };
+                stats::winsorize(samples, 5.0);
+                summ = Some(stats::Summary::new(samples));
 
-            stats::winsorize(samples, 5.0);
-            let summ5 = stats::Summary::new(samples);
+                for p in samples.iter_mut() {
+                    self.bench_n(5 * n, |x| f(x));
+                    *p = self.ns_per_iter() as f64;
+                };
 
-            let now = precise_time_ns();
-            let loop_run = now - loop_start;
+                stats::winsorize(samples, 5.0);
+                summ5 = Some(stats::Summary::new(samples));
+            });
+            let summ = summ.unwrap();
+            let summ5 = summ5.unwrap();
 
             // If we've run for 100ms and seem to have converged to a
             // stable median.
-            if loop_run > 100_000_000 &&
+            if loop_run.num_milliseconds() > 100 &&
                 summ.median_abs_dev_pct < 1.0 &&
                 summ.median - summ5.median < summ5.median_abs_dev {
                 return summ5;
             }
 
-            total_run += loop_run;
+            total_run = total_run + loop_run;
             // Longest we ever run for is 3s.
-            if total_run > 3_000_000_000 {
+            if total_run.num_seconds() > 3 {
                 return summ5;
             }
 
@@ -1367,13 +1364,13 @@ impl Bencher {
 
 pub mod bench {
     use std::cmp;
+    use std::time::Duration;
     use super::{Bencher, BenchSamples};
 
     pub fn benchmark(f: |&mut Bencher|) -> BenchSamples {
         let mut bs = Bencher {
             iterations: 0,
-            ns_start: 0,
-            ns_end: 0,
+            dur: Duration::nanoseconds(0),
             bytes: 0
         };
 
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index bbe6002717c..3211d03a7c0 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -11,7 +11,8 @@
 //! Simple time handling.
 
 #![crate_name = "time"]
-#![experimental]
+#![deprecated = "use the http://github.com/rust-lang/time crate instead"]
+#![allow(deprecated)]
 
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
diff --git a/src/test/auxiliary/lint-unused-extern-crate.rs b/src/test/auxiliary/lint-unused-extern-crate.rs
new file mode 100644
index 00000000000..2661b1f4eb4
--- /dev/null
+++ b/src/test/auxiliary/lint-unused-extern-crate.rs
@@ -0,0 +1,11 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index ac6104cc38b..bbbd878e8b8 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -8,18 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate time;
-
 use std::collections::{TrieMap, TreeMap, HashMap, HashSet};
 use std::os;
 use std::rand::{Rng, IsaacRng, SeedableRng};
+use std::time::Duration;
 use std::uint;
 
 fn timed(label: &str, f: ||) {
-    let start = time::precise_time_s();
-    f();
-    let end = time::precise_time_s();
-    println!("  {}: {}", label, end - start);
+    println!("  {}: {}", label, Duration::span(f));
 }
 
 trait MutableMap {
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 8151f2718e3..15d89bebf75 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -12,30 +12,27 @@
 
 extern crate collections;
 extern crate rand;
-extern crate time;
 
 use std::collections::BitvSet;
+use std::collections::HashSet;
 use std::collections::TreeSet;
 use std::hash::Hash;
-use std::collections::HashSet;
 use std::os;
+use std::time::Duration;
 use std::uint;
 
 struct Results {
-    sequential_ints: f64,
-    random_ints: f64,
-    delete_ints: f64,
+    sequential_ints: Duration,
+    random_ints: Duration,
+    delete_ints: Duration,
 
-    sequential_strings: f64,
-    random_strings: f64,
-    delete_strings: f64
+    sequential_strings: Duration,
+    random_strings: Duration,
+    delete_strings: Duration,
 }
 
-fn timed(result: &mut f64, op: ||) {
-    let start = time::precise_time_s();
-    op();
-    let end = time::precise_time_s();
-    *result = (end - start);
+fn timed(result: &mut Duration, op: ||) {
+    *result = Duration::span(op);
 }
 
 trait MutableSet<T> {
@@ -150,7 +147,7 @@ fn write_header(header: &str) {
     println!("{}", header);
 }
 
-fn write_row(label: &str, value: f64) {
+fn write_row(label: &str, value: Duration) {
     println!("{:30s} {} s\n", label, value);
 }
 
@@ -166,13 +163,13 @@ fn write_results(label: &str, results: &Results) {
 
 fn empty_results() -> Results {
     Results {
-        sequential_ints: 0.0,
-        random_ints: 0.0,
-        delete_ints: 0.0,
+        sequential_ints: Duration::seconds(0),
+        random_ints: Duration::seconds(0),
+        delete_ints: Duration::seconds(0),
 
-        sequential_strings: 0.0,
-        random_strings: 0.0,
-        delete_strings: 0.0,
+        sequential_strings: Duration::seconds(0),
+        random_strings: Duration::seconds(0),
+        delete_strings: Duration::seconds(0),
     }
 }
 
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 39057215b5e..24bd26b0288 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -13,16 +13,14 @@
 
 #![feature(macro_rules)]
 
-extern crate time;
-
-use time::precise_time_s;
-use std::rand;
-use std::rand::Rng;
+use std::io::File;
 use std::mem::swap;
 use std::os;
+use std::rand::Rng;
+use std::rand;
 use std::str;
+use std::time::Duration;
 use std::vec;
-use std::io::File;
 
 fn main() {
     let argv = os::args();
@@ -56,11 +54,9 @@ fn maybe_run_test(argv: &[String], name: String, test: ||) {
         return
     }
 
-    let start = precise_time_s();
-    test();
-    let stop = precise_time_s();
+    let dur = Duration::span(test);
 
-    println!("{}:\t\t{} ms", name, (stop - start) * 1000.0);
+    println!("{}:\t\t{} ms", name, dur.num_milliseconds());
 }
 
 fn shift_push() {
diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs
index 34479f296bb..c2383add929 100644
--- a/src/test/bench/msgsend-pipes-shared.rs
+++ b/src/test/bench/msgsend-pipes-shared.rs
@@ -18,11 +18,10 @@
 // different scalability characteristics compared to the select
 // version.
 
-extern crate time;
-
 use std::comm;
 use std::os;
 use std::task;
+use std::time::Duration;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -58,36 +57,39 @@ fn run(args: &[String]) {
     let size = from_str::<uint>(args[1].as_slice()).unwrap();
     let workers = from_str::<uint>(args[2].as_slice()).unwrap();
     let num_bytes = 100;
-    let start = time::precise_time_s();
-    let mut worker_results = Vec::new();
-    for _ in range(0u, workers) {
-        let to_child = to_child.clone();
-        worker_results.push(task::try_future(proc() {
-            for _ in range(0u, size / workers) {
-                //println!("worker {}: sending {} bytes", i, num_bytes);
-                to_child.send(bytes(num_bytes));
-            }
-            //println!("worker {} exiting", i);
-        }));
-    }
-    task::spawn(proc() {
-        server(&from_parent, &to_parent);
-    });
+    let mut result = None;
+    let mut p = Some((to_child, to_parent, from_parent));
+    let dur = Duration::span(|| {
+        let (to_child, to_parent, from_parent) = p.take().unwrap();
+        let mut worker_results = Vec::new();
+        for _ in range(0u, workers) {
+            let to_child = to_child.clone();
+            worker_results.push(task::try_future(proc() {
+                for _ in range(0u, size / workers) {
+                    //println!("worker {}: sending {} bytes", i, num_bytes);
+                    to_child.send(bytes(num_bytes));
+                }
+                //println!("worker {} exiting", i);
+            }));
+        }
+        task::spawn(proc() {
+            server(&from_parent, &to_parent);
+        });
 
-    for r in worker_results.into_iter() {
-        r.unwrap();
-    }
+        for r in worker_results.into_iter() {
+            r.unwrap();
+        }
 
-    //println!("sending stop message");
-    to_child.send(stop);
-    move_out(to_child);
-    let result = from_child.recv();
-    let end = time::precise_time_s();
-    let elapsed = end - start;
+        //println!("sending stop message");
+        to_child.send(stop);
+        move_out(to_child);
+        result = Some(from_child.recv());
+    });
+    let result = result.unwrap();
     print!("Count is {}\n", result);
-    print!("Test took {} seconds\n", elapsed);
-    let thruput = ((size / workers * workers) as f64) / (elapsed as f64);
-    print!("Throughput={} per sec\n", thruput);
+    print!("Test took {} ms\n", dur.num_milliseconds());
+    let thruput = ((size / workers * workers) as f64) / (dur.num_milliseconds() as f64);
+    print!("Throughput={} per sec\n", thruput / 1000.0);
     assert_eq!(result, num_bytes * size);
 }
 
diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs
index 7a06b43ba2d..8d05dfdb7cd 100644
--- a/src/test/bench/msgsend-pipes.rs
+++ b/src/test/bench/msgsend-pipes.rs
@@ -14,10 +14,9 @@
 //
 // I *think* it's the same, more or less.
 
-extern crate time;
-
 use std::os;
 use std::task;
+use std::time::Duration;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -52,22 +51,13 @@ fn run(args: &[String]) {
     let size = from_str::<uint>(args[1].as_slice()).unwrap();
     let workers = from_str::<uint>(args[2].as_slice()).unwrap();
     let num_bytes = 100;
-    let start = time::precise_time_s();
-    let mut worker_results = Vec::new();
-    let from_parent = if workers == 1 {
-        let (to_child, from_parent) = channel();
-        worker_results.push(task::try_future(proc() {
-            for _ in range(0u, size / workers) {
-                //println!("worker {}: sending {} bytes", i, num_bytes);
-                to_child.send(bytes(num_bytes));
-            }
-            //println!("worker {} exiting", i);
-        }));
-        from_parent
-    } else {
-        let (to_child, from_parent) = channel();
-        for _ in range(0u, workers) {
-            let to_child = to_child.clone();
+    let mut result = None;
+    let mut to_parent = Some(to_parent);
+    let dur = Duration::span(|| {
+        let to_parent = to_parent.take().unwrap();
+        let mut worker_results = Vec::new();
+        let from_parent = if workers == 1 {
+            let (to_child, from_parent) = channel();
             worker_results.push(task::try_future(proc() {
                 for _ in range(0u, size / workers) {
                     //println!("worker {}: sending {} bytes", i, num_bytes);
@@ -75,27 +65,39 @@ fn run(args: &[String]) {
                 }
                 //println!("worker {} exiting", i);
             }));
-        }
-        from_parent
-    };
-    task::spawn(proc() {
-        server(&from_parent, &to_parent);
-    });
+            from_parent
+        } else {
+            let (to_child, from_parent) = channel();
+            for _ in range(0u, workers) {
+                let to_child = to_child.clone();
+                worker_results.push(task::try_future(proc() {
+                    for _ in range(0u, size / workers) {
+                        //println!("worker {}: sending {} bytes", i, num_bytes);
+                        to_child.send(bytes(num_bytes));
+                    }
+                    //println!("worker {} exiting", i);
+                }));
+            }
+            from_parent
+        };
+        task::spawn(proc() {
+            server(&from_parent, &to_parent);
+        });
 
-    for r in worker_results.into_iter() {
-        r.unwrap();
-    }
+        for r in worker_results.into_iter() {
+            r.unwrap();
+        }
 
-    //println!("sending stop message");
-    //to_child.send(stop);
-    //move_out(to_child);
-    let result = from_child.recv();
-    let end = time::precise_time_s();
-    let elapsed = end - start;
+        //println!("sending stop message");
+        //to_child.send(stop);
+        //move_out(to_child);
+        result = Some(from_child.recv());
+    });
+    let result = result.unwrap();
     print!("Count is {}\n", result);
-    print!("Test took {} seconds\n", elapsed);
-    let thruput = ((size / workers * workers) as f64) / (elapsed as f64);
-    print!("Throughput={} per sec\n", thruput);
+    print!("Test took {} ms\n", dur.num_milliseconds());
+    let thruput = ((size / workers * workers) as f64) / (dur.num_milliseconds() as f64);
+    print!("Throughput={} per sec\n", thruput / 1000.0);
     assert_eq!(result, num_bytes * size);
 }
 
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index 1a9ffd68284..d06e6c8cd19 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -18,10 +18,9 @@
 // no-pretty-expanded FIXME #15189
 // ignore-lexer-test FIXME #15679
 
-extern crate time;
-
-use std::sync::{Arc, Future, Mutex};
 use std::os;
+use std::sync::{Arc, Future, Mutex};
+use std::time::Duration;
 use std::uint;
 
 // A poor man's pipe.
@@ -77,38 +76,38 @@ fn main() {
 
     let (mut num_chan, num_port) = init();
 
-    let start = time::precise_time_s();
-
-    // create the ring
-    let mut futures = Vec::new();
-
-    for i in range(1u, num_tasks) {
-        //println!("spawning %?", i);
-        let (new_chan, num_port) = init();
-        let num_chan_2 = num_chan.clone();
-        let new_future = Future::spawn(proc() {
-            thread_ring(i, msg_per_task, num_chan_2, num_port)
-        });
-        futures.push(new_future);
-        num_chan = new_chan;
-    };
-
-    // do our iteration
-    thread_ring(0, msg_per_task, num_chan, num_port);
-
-    // synchronize
-    for f in futures.iter_mut() {
-        f.get()
-    }
-
-    let stop = time::precise_time_s();
+    let mut p = Some((num_chan, num_port));
+    let dur = Duration::span(|| {
+        let (mut num_chan, num_port) = p.take().unwrap();
+
+        // create the ring
+        let mut futures = Vec::new();
+
+        for i in range(1u, num_tasks) {
+            //println!("spawning %?", i);
+            let (new_chan, num_port) = init();
+            let num_chan_2 = num_chan.clone();
+            let new_future = Future::spawn(proc() {
+                thread_ring(i, msg_per_task, num_chan_2, num_port)
+            });
+            futures.push(new_future);
+            num_chan = new_chan;
+        };
+
+        // do our iteration
+        thread_ring(0, msg_per_task, num_chan, num_port);
+
+        // synchronize
+        for f in futures.iter_mut() {
+            f.get()
+        }
+    });
 
     // all done, report stats.
     let num_msgs = num_tasks * msg_per_task;
-    let elapsed = (stop - start);
-    let rate = (num_msgs as f64) / elapsed;
+    let rate = (num_msgs as f64) / (dur.num_milliseconds() as f64);
 
-    println!("Sent {} messages in {} seconds", num_msgs, elapsed);
-    println!("  {} messages / second", rate);
-    println!("  {} μs / message", 1000000. / rate);
+    println!("Sent {} messages in {} ms", num_msgs, dur.num_milliseconds());
+    println!("  {} messages / second", rate / 1000.0);
+    println!("  {} μs / message", 1000000. / rate / 1000.0);
 }
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
index 5e192a14793..03066d40512 100644
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ b/src/test/bench/msgsend-ring-rw-arcs.rs
@@ -18,10 +18,9 @@
 // no-pretty-expanded FIXME #15189
 // ignore-lexer-test FIXME #15679
 
-extern crate time;
-
-use std::sync::{RWLock, Arc, Future};
 use std::os;
+use std::sync::{RWLock, Arc, Future};
+use std::time::Duration;
 use std::uint;
 
 // A poor man's pipe.
@@ -77,38 +76,38 @@ fn main() {
 
     let (mut num_chan, num_port) = init();
 
-    let start = time::precise_time_s();
-
-    // create the ring
-    let mut futures = Vec::new();
-
-    for i in range(1u, num_tasks) {
-        //println!("spawning %?", i);
-        let (new_chan, num_port) = init();
-        let num_chan_2 = num_chan.clone();
-        let new_future = Future::spawn(proc() {
-            thread_ring(i, msg_per_task, num_chan_2, num_port)
-        });
-        futures.push(new_future);
-        num_chan = new_chan;
-    };
-
-    // do our iteration
-    thread_ring(0, msg_per_task, num_chan, num_port);
-
-    // synchronize
-    for f in futures.iter_mut() {
-        let _ = f.get();
-    }
-
-    let stop = time::precise_time_s();
+    let mut p = Some((num_chan, num_port));
+    let dur = Duration::span(|| {
+        let (mut num_chan, num_port) = p.take().unwrap();
+
+        // create the ring
+        let mut futures = Vec::new();
+
+        for i in range(1u, num_tasks) {
+            //println!("spawning %?", i);
+            let (new_chan, num_port) = init();
+            let num_chan_2 = num_chan.clone();
+            let new_future = Future::spawn(proc() {
+                thread_ring(i, msg_per_task, num_chan_2, num_port)
+            });
+            futures.push(new_future);
+            num_chan = new_chan;
+        };
+
+        // do our iteration
+        thread_ring(0, msg_per_task, num_chan, num_port);
+
+        // synchronize
+        for f in futures.iter_mut() {
+            let _ = f.get();
+        }
+    });
 
     // all done, report stats.
     let num_msgs = num_tasks * msg_per_task;
-    let elapsed = (stop - start);
-    let rate = (num_msgs as f64) / elapsed;
+    let rate = (num_msgs as f64) / (dur.num_milliseconds() as f64);
 
-    println!("Sent {} messages in {} seconds", num_msgs, elapsed);
-    println!("  {} messages / second", rate);
-    println!("  {} μs / message", 1000000. / rate);
+    println!("Sent {} messages in {} ms", num_msgs, dur.num_milliseconds());
+    println!("  {} messages / second", rate / 1000.0);
+    println!("  {} μs / message", 1000000. / rate / 1000.0);
 }
diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs
index 7fa13d6074d..9cc86e91fbe 100644
--- a/src/test/bench/shootout-pfib.rs
+++ b/src/test/bench/shootout-pfib.rs
@@ -19,11 +19,11 @@
 */
 
 extern crate getopts;
-extern crate time;
 
 use std::os;
 use std::result::{Ok, Err};
 use std::task;
+use std::time::Duration;
 
 fn fib(n: int) -> int {
     fn pfib(tx: &Sender<int>, n: int) {
@@ -107,13 +107,11 @@ fn main() {
 
         for n in range(1, max + 1) {
             for _ in range(0u, num_trials) {
-                let start = time::precise_time_ns();
-                let fibn = fib(n);
-                let stop = time::precise_time_ns();
+                let mut fibn = None;
+                let dur = Duration::span(|| fibn = Some(fib(n)));
+                let fibn = fibn.unwrap();
 
-                let elapsed = stop - start;
-
-                println!("{}\t{}\t{}", n, fibn, elapsed.to_string());
+                println!("{}\t{}\t{}", n, fibn, dur);
             }
         }
     }
diff --git a/src/test/bench/std-smallintmap.rs b/src/test/bench/std-smallintmap.rs
index cdcb88d87c6..576d96ba2a3 100644
--- a/src/test/bench/std-smallintmap.rs
+++ b/src/test/bench/std-smallintmap.rs
@@ -10,11 +10,9 @@
 
 // Microbenchmark for the smallintmap library
 
-extern crate collections;
-extern crate time;
-
 use std::collections::VecMap;
 use std::os;
+use std::time::Duration;
 use std::uint;
 
 fn append_sequential(min: uint, max: uint, map: &mut VecMap<uint>) {
@@ -41,25 +39,22 @@ fn main() {
     let max = from_str::<uint>(args[1].as_slice()).unwrap();
     let rep = from_str::<uint>(args[2].as_slice()).unwrap();
 
-    let mut checkf = 0.0;
-    let mut appendf = 0.0;
+    let mut checkf = Duration::seconds(0);
+    let mut appendf = Duration::seconds(0);
 
     for _ in range(0u, rep) {
         let mut map = VecMap::new();
-        let start = time::precise_time_s();
-        append_sequential(0u, max, &mut map);
-        let mid = time::precise_time_s();
-        check_sequential(0u, max, &map);
-        let end = time::precise_time_s();
+        let d1 = Duration::span(|| append_sequential(0u, max, &mut map));
+        let d2 = Duration::span(|| check_sequential(0u, max, &map));
 
-        checkf += (end - mid) as f64;
-        appendf += (mid - start) as f64;
+        checkf = checkf + d2;
+        appendf = appendf + d1;
     }
 
     let maxf = max as f64;
 
     println!("insert(): {} seconds\n", checkf);
-    println!("        : {} op/sec\n", maxf/checkf);
+    println!("        : {} op/ms\n", maxf / checkf.num_milliseconds() as f64);
     println!("get()   : {} seconds\n", appendf);
-    println!("        : {} op/sec\n", maxf/appendf);
+    println!("        : {} op/ms\n", maxf / appendf.num_milliseconds() as f64);
 }
diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs
index 5d96c90197c..19c3045f0e7 100644
--- a/src/test/bench/task-perf-alloc-unwind.rs
+++ b/src/test/bench/task-perf-alloc-unwind.rs
@@ -10,11 +10,9 @@
 
 #![feature(unsafe_destructor)]
 
-extern crate time;
-
-use time::precise_time_s;
 use std::os;
 use std::task;
+use std::time::Duration;
 
 #[deriving(Clone)]
 enum List<T> {
@@ -37,11 +35,12 @@ fn main() {
 
 fn run(repeat: int, depth: int) {
     for _ in range(0, repeat) {
-        println!("starting {:.4f}", precise_time_s());
-        task::try(proc() {
-            recurse_or_panic(depth, None)
+        let dur = Duration::span(|| {
+            task::try(proc() {
+                recurse_or_panic(depth, None)
+            });
         });
-        println!("stopping {:.4f}", precise_time_s());
+        println!("iter: {}", dur);
     }
 }
 
@@ -72,7 +71,6 @@ fn r(l: Box<nillist>) -> r {
 
 fn recurse_or_panic(depth: int, st: Option<State>) {
     if depth == 0 {
-        println!("unwinding {:.4f}", precise_time_s());
         panic!();
     } else {
         let depth = depth - 1;
diff --git a/src/test/compile-fail/lint-unused-extern-crate.rs b/src/test/compile-fail/lint-unused-extern-crate.rs
index a63e8e913f4..93190a0ffe5 100644
--- a/src/test/compile-fail/lint-unused-extern-crate.rs
+++ b/src/test/compile-fail/lint-unused-extern-crate.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// aux-build:lint-unused-extern-crate.rs
+
 #![feature(globs)]
 #![deny(unused_extern_crates)]
 #![allow(unused_variables)]
@@ -19,14 +21,14 @@ extern crate "collections" as collecs; // no error, it is used
 extern crate rand; // no error, the use marks it as used
                    // even if imported objects aren't used
 
-extern crate time; // no error, the use * marks it as used
+extern crate "lint-unused-extern-crate" as other; // no error, the use * marks it as used
 
 #[allow(unused_imports)]
 use rand::isaac::IsaacRng;
 
-use time::*;
+use other::*;
 
 fn main() {
     let x: collecs::vec::Vec<uint> = Vec::new();
-    let y = now();
+    let y = foo();
 }