From 999bdeca88a06938ac1e1c608091d3afe4d7e173 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 5 Jul 2015 23:20:00 -0700 Subject: [PATCH] Stabilize the Duration API This commit stabilizes the `std::time` module and the `Duration` type. `Duration::span` remains unstable, and the `Display` implementation for `Duration` has been removed as it is still being reworked and all trait implementations for stable types are de facto stable. This is a [breaking-change] to those using `Duration`'s `Display` implementation. --- src/librustc/lib.rs | 1 - src/librustc/metadata/loader.rs | 2 +- src/librustc/util/common.rs | 4 +- src/libstd/sys/unix/condvar.rs | 4 +- src/libstd/sys/unix/net.rs | 8 +-- src/libstd/sys/unix/thread.rs | 4 +- src/libstd/sys/windows/mod.rs | 6 +- src/libstd/time/duration.rs | 67 +++++++---------------- src/libstd/time/mod.rs | 2 +- src/libtest/lib.rs | 3 +- src/test/bench/core-map.rs | 2 +- src/test/bench/core-set.rs | 2 +- src/test/bench/core-std.rs | 2 +- src/test/bench/msgsend-pipes-shared.rs | 4 +- src/test/bench/msgsend-pipes.rs | 4 +- src/test/bench/msgsend-ring-mutex-arcs.rs | 4 +- src/test/bench/shootout-pfib.rs | 2 +- src/test/bench/std-smallintmap.rs | 8 +-- src/test/bench/task-perf-alloc-unwind.rs | 2 +- 19 files changed, 51 insertions(+), 80 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 1a15d98d531..bb44abc4f07 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -33,7 +33,6 @@ #![feature(collections)] #![feature(const_fn)] #![feature(core)] -#![feature(duration)] #![feature(duration_span)] #![feature(dynamic_lib)] #![feature(enumset)] diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 81acaf66e08..2f481f70aaf 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -722,7 +722,7 @@ fn get_metadata_section(target: &Target, filename: &Path) let dur = Duration::span(|| { ret = Some(get_metadata_section_imp(target, filename)); }); - info!("reading {:?} => {}", filename.file_name().unwrap(), dur); + info!("reading {:?} => {:?}", filename.file_name().unwrap(), dur); return ret.unwrap();; } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 03aa4bc2ead..db0f820e11b 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -57,8 +57,8 @@ pub fn time(do_it: bool, what: &str, u: U, f: F) -> T where // Hack up our own formatting for the duration to make it easier for scripts // to parse (always use the same number of decimal places and the same unit). const NANOS_PER_SEC: f64 = 1_000_000_000.0; - let secs = dur.secs() as f64; - let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC; + let secs = dur.as_secs() as f64; + let secs = secs + dur.subsec_nanos() as f64 / NANOS_PER_SEC; let mem_string = match get_resident() { Some(n) => { diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 9dd8df7524d..5d18c1d6280 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -61,11 +61,11 @@ impl Condvar { let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut()); debug_assert_eq!(r, 0); - let nsec = dur.extra_nanos() as libc::c_long + + let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long; let extra = (nsec / 1_000_000_000) as libc::time_t; let nsec = nsec % 1_000_000_000; - let seconds = dur.secs() as libc::time_t; + let seconds = dur.as_secs() as libc::time_t; let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| { s.checked_add(seconds) diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 37eb7fd2ac8..e65f64f2029 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -79,19 +79,19 @@ impl Socket { pub fn set_timeout(&self, dur: Option, kind: libc::c_int) -> io::Result<()> { let timeout = match dur { Some(dur) => { - if dur.secs() == 0 && dur.extra_nanos() == 0 { + if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { return Err(io::Error::new(io::ErrorKind::InvalidInput, "cannot set a 0 duration timeout")); } - let secs = if dur.secs() > libc::time_t::max_value() as u64 { + let secs = if dur.as_secs() > libc::time_t::max_value() as u64 { libc::time_t::max_value() } else { - dur.secs() as libc::time_t + dur.as_secs() as libc::time_t }; let mut timeout = libc::timeval { tv_sec: secs, - tv_usec: (dur.extra_nanos() / 1000) as libc::suseconds_t, + tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t, }; if timeout.tv_sec == 0 && timeout.tv_usec == 0 { timeout.tv_usec = 1; diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 67ecd4d9229..8efd76b9abd 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -131,8 +131,8 @@ impl Thread { pub fn sleep(dur: Duration) { let mut ts = libc::timespec { - tv_sec: dur.secs() as libc::time_t, - tv_nsec: dur.extra_nanos() as libc::c_long, + tv_sec: dur.as_secs() as libc::time_t, + tv_nsec: dur.subsec_nanos() as libc::c_long, }; // If we're awoken with a signal then the return value will be -1 and diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index b6d080109df..b38945d8916 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -162,10 +162,10 @@ fn dur2timeout(dur: Duration) -> libc::DWORD { // * Nanosecond precision is rounded up // * Greater than u32::MAX milliseconds (50 days) is rounded up to INFINITE // (never time out). - dur.secs().checked_mul(1000).and_then(|ms| { - ms.checked_add((dur.extra_nanos() as u64) / 1_000_000) + dur.as_secs().checked_mul(1000).and_then(|ms| { + ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000) }).and_then(|ms| { - ms.checked_add(if dur.extra_nanos() % 1_000_000 > 0 {1} else {0}) + ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 {1} else {0}) }).map(|ms| { if ms > ::max_value() as u64 { libc::INFINITE diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 28eaed40da8..ee287484256 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -8,14 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Temporal quantification - -#![unstable(feature = "duration", reason = "recently added API per RFC 1040")] - #[cfg(stage0)] use prelude::v1::*; -use fmt; use ops::{Add, Sub, Mul, Div}; use sys::time::SteadyTime; @@ -43,11 +38,12 @@ const MILLIS_PER_SEC: u64 = 1_000; /// let five_seconds = Duration::new(5, 0); /// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5); /// -/// assert_eq!(five_seconds_and_five_nanos.secs(), 5); -/// assert_eq!(five_seconds_and_five_nanos.extra_nanos(), 5); +/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5); +/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5); /// /// let ten_millis = Duration::from_millis(10); /// ``` +#[stable(feature = "duration", since = "1.3.0")] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct Duration { secs: u64, @@ -60,6 +56,7 @@ impl Duration { /// /// If the nanoseconds is greater than 1 billion (the number of nanoseconds /// in a second), then it will carry over into the seconds provided. + #[stable(feature = "duration", since = "1.3.0")] pub fn new(secs: u64, nanos: u32) -> Duration { let secs = secs + (nanos / NANOS_PER_SEC) as u64; let nanos = nanos % NANOS_PER_SEC; @@ -79,11 +76,13 @@ impl Duration { } /// Creates a new `Duration` from the specified number of seconds. + #[stable(feature = "duration", since = "1.3.0")] pub fn from_secs(secs: u64) -> Duration { Duration { secs: secs, nanos: 0 } } /// Creates a new `Duration` from the specified number of milliseconds. + #[stable(feature = "duration", since = "1.3.0")] pub fn from_millis(millis: u64) -> Duration { let secs = millis / MILLIS_PER_SEC; let nanos = ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI; @@ -94,14 +93,16 @@ impl Duration { /// /// The extra precision represented by this duration is ignored (e.g. extra /// nanoseconds are not represented in the returned value). - pub fn secs(&self) -> u64 { self.secs } + #[stable(feature = "duration", since = "1.3.0")] + pub fn as_secs(&self) -> u64 { self.secs } /// Returns the nanosecond precision represented by this duration. /// /// This method does **not** return the length of the duration when /// represented by nanoseconds. The returned number always represents a /// fractional portion of a second (e.g. it is less than one billion). - pub fn extra_nanos(&self) -> u32 { self.nanos } + #[stable(feature = "duration", since = "1.3.0")] + pub fn subsec_nanos(&self) -> u32 { self.nanos } } impl Add for Duration { @@ -167,20 +168,6 @@ impl Div for Duration { } } -impl fmt::Display for Duration { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match (self.secs, self.nanos) { - (s, 0) => write!(f, "{}s", s), - (0, n) if n % NANOS_PER_MILLI == 0 => write!(f, "{}ms", - n / NANOS_PER_MILLI), - (0, n) if n % 1_000 == 0 => write!(f, "{}µs", n / 1_000), - (0, n) => write!(f, "{}ns", n), - (s, n) => write!(f, "{}.{}s", s, - format!("{:09}", n).trim_right_matches('0')) - } - } -} - #[cfg(test)] mod tests { use prelude::v1::*; @@ -198,20 +185,20 @@ mod tests { #[test] fn secs() { - assert_eq!(Duration::new(0, 0).secs(), 0); - assert_eq!(Duration::from_secs(1).secs(), 1); - assert_eq!(Duration::from_millis(999).secs(), 0); - assert_eq!(Duration::from_millis(1001).secs(), 1); + assert_eq!(Duration::new(0, 0).as_secs(), 0); + assert_eq!(Duration::from_secs(1).as_secs(), 1); + assert_eq!(Duration::from_millis(999).as_secs(), 0); + assert_eq!(Duration::from_millis(1001).as_secs(), 1); } #[test] fn nanos() { - assert_eq!(Duration::new(0, 0).extra_nanos(), 0); - assert_eq!(Duration::new(0, 5).extra_nanos(), 5); - assert_eq!(Duration::new(0, 1_000_000_001).extra_nanos(), 1); - assert_eq!(Duration::from_secs(1).extra_nanos(), 0); - assert_eq!(Duration::from_millis(999).extra_nanos(), 999 * 1_000_000); - assert_eq!(Duration::from_millis(1001).extra_nanos(), 1 * 1_000_000); + assert_eq!(Duration::new(0, 0).subsec_nanos(), 0); + assert_eq!(Duration::new(0, 5).subsec_nanos(), 5); + assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1); + assert_eq!(Duration::from_secs(1).subsec_nanos(), 0); + assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000); + assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000); } #[test] @@ -258,18 +245,4 @@ mod tests { assert_eq!(Duration::new(99, 999_999_000) / 100, Duration::new(0, 999_999_990)); } - - #[test] - fn display() { - assert_eq!(Duration::new(0, 2).to_string(), "2ns"); - assert_eq!(Duration::new(0, 2_000_000).to_string(), "2ms"); - assert_eq!(Duration::new(2, 0).to_string(), "2s"); - assert_eq!(Duration::new(2, 2).to_string(), "2.000000002s"); - assert_eq!(Duration::new(2, 2_000_000).to_string(), - "2.002s"); - assert_eq!(Duration::new(0, 2_000_002).to_string(), - "2000002ns"); - assert_eq!(Duration::new(2, 2_000_002).to_string(), - "2.002000002s"); - } } diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs index d535b195519..29df882a042 100644 --- a/src/libstd/time/mod.rs +++ b/src/libstd/time/mod.rs @@ -10,7 +10,7 @@ //! Temporal quantification. -#![unstable(feature = "time")] +#![stable(feature = "time", since = "1.3.0")] pub use self::duration::Duration; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 7777ea51f82..a7fb88215b7 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -36,7 +36,6 @@ #![feature(asm)] #![feature(box_syntax)] -#![feature(duration)] #![feature(duration_span)] #![feature(fnbox)] #![feature(iter_cmp)] @@ -1105,7 +1104,7 @@ impl Bencher { } pub fn ns_elapsed(&mut self) -> u64 { - self.dur.secs() * 1_000_000_000 + (self.dur.extra_nanos() as u64) + self.dur.as_secs() * 1_000_000_000 + (self.dur.subsec_nanos() as u64) } pub fn ns_per_iter(&mut self) -> u64 { diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index af61b0aa0cd..ebb8036bacf 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -16,7 +16,7 @@ use std::__rand::{Rng, thread_rng}; use std::time::Duration; fn timed(label: &str, f: F) where F: FnMut() { - println!(" {}: {}", label, Duration::span(f)); + println!(" {}: {:?}", label, Duration::span(f)); } trait MutableMap { diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index d2537e09901..f4ee020d6e7 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -153,7 +153,7 @@ fn write_header(header: &str) { } fn write_row(label: &str, value: Duration) { - println!("{:30} {} s\n", label, value); + println!("{:30} {:?} s\n", label, value); } fn write_results(label: &str, results: &Results) { diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index e7d64dfe2c5..26fb3630487 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -51,7 +51,7 @@ fn maybe_run_test(argv: &[String], name: String, test: F) where F: FnOnce() { let dur = Duration::span(test); - println!("{}:\t\t{}", name, dur); + println!("{}:\t\t{:?}", name, dur); } fn shift_push() { diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 2b7e204423e..b210f5ac26a 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -88,8 +88,8 @@ fn run(args: &[String]) { }); let result = result.unwrap(); print!("Count is {}\n", result); - print!("Test took {}\n", dur); - let thruput = ((size / workers * workers) as f64) / (dur.secs() as f64); + print!("Test took {:?}\n", dur); + let thruput = ((size / workers * workers) as f64) / (dur.as_secs() as f64); print!("Throughput={} per sec\n", thruput); assert_eq!(result, num_bytes * size); } diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 5a541420d2a..056905f1ef6 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -95,8 +95,8 @@ fn run(args: &[String]) { }); let result = result.unwrap(); print!("Count is {}\n", result); - print!("Test took {}\n", dur); - let thruput = ((size / workers * workers) as f64) / (dur.secs() as f64); + print!("Test took {:?}\n", dur); + let thruput = ((size / workers * workers) as f64) / (dur.as_secs() as f64); print!("Throughput={} per sec\n", thruput); 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 24ecaf4b024..b7f9dc94a0b 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -107,9 +107,9 @@ fn main() { // all done, report stats. let num_msgs = num_tasks * msg_per_task; - let rate = (num_msgs as f64) / (dur.secs() as f64); + let rate = (num_msgs as f64) / (dur.as_secs() as f64); - println!("Sent {} messages in {}", num_msgs, dur); + println!("Sent {} messages in {:?}", num_msgs, dur); println!(" {} messages / second", rate); println!(" {} μs / message", 1000000. / rate); } diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 2d5aae30ae8..b7553dc7c70 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -114,7 +114,7 @@ fn main() { let dur = Duration::span(|| fibn = Some(fib(n))); let fibn = fibn.unwrap(); - println!("{}\t{}\t{}", n, fibn, dur); + println!("{}\t{}\t{:?}", n, fibn, dur); } } } diff --git a/src/test/bench/std-smallintmap.rs b/src/test/bench/std-smallintmap.rs index 6a39a6db0c7..64f2381d1c3 100644 --- a/src/test/bench/std-smallintmap.rs +++ b/src/test/bench/std-smallintmap.rs @@ -54,8 +54,8 @@ fn main() { let maxf = max as f64; - println!("insert(): {} seconds\n", checkf); - println!(" : {} op/s\n", maxf / checkf.secs() as f64); - println!("get() : {} seconds\n", appendf); - println!(" : {} op/s\n", maxf / appendf.secs() as f64); + println!("insert(): {:?} seconds\n", checkf); + println!(" : {} op/s\n", maxf / checkf.as_secs() as f64); + println!("get() : {:?} seconds\n", appendf); + println!(" : {} op/s\n", maxf / appendf.as_secs() as f64); } diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 3bd7b781251..5f34d0f6301 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -36,7 +36,7 @@ fn run(repeat: isize, depth: isize) { recurse_or_panic(depth, None) }).join(); }); - println!("iter: {}", dur); + println!("iter: {:?}", dur); } }