diff --git a/mk/crates.mk b/mk/crates.mk index 895819a5a50..4ac4abe9063 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -83,7 +83,7 @@ DEPS_fourcc := syntax std DEPS_hexfloat := syntax std DEPS_num := std rand DEPS_test := std collections getopts serialize term time regex -DEPS_time := std serialize +DEPS_time := std serialize sync DEPS_rand := std DEPS_url := std collections DEPS_workcache := std serialize collections log diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index b580626c9c3..0e67076dc08 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -24,6 +24,8 @@ #[cfg(test)] #[phase(syntax, link)] extern crate log; extern crate serialize; extern crate libc; +#[cfg(target_os = "macos")] +extern crate sync; use std::io::BufReader; use std::num; @@ -159,10 +161,16 @@ pub fn precise_time_ns() -> u64 { #[cfg(target_os = "macos")] fn os_precise_time_ns() -> u64 { - let time = unsafe { imp::mach_absolute_time() }; - let mut info = libc::mach_timebase_info { numer: 0, denom: 0 }; - unsafe { imp::mach_timebase_info(&mut info); } - return time * ((info.numer / info.denom) as u64); + static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0, + denom: 0 }; + static mut ONCE: sync::one::Once = sync::one::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(windows), not(target_os = "macos"))] @@ -1080,11 +1088,13 @@ pub fn strftime(format: &str, tm: &Tm) -> StrBuf { #[cfg(test)] mod tests { + extern crate test; use super::{Timespec, get_time, precise_time_ns, precise_time_s, tzset, at_utc, at, strptime}; use std::f64; use std::result::{Err, Ok}; + use self::test::Bencher; #[cfg(windows)] fn set_time_zone() { @@ -1520,4 +1530,9 @@ mod tests { test_strftime(); test_timespec_eq_ord(); } + + #[bench] + fn bench_precise_time_ns(b: &mut Bencher) { + b.iter(|| precise_time_ns()) + } }