diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 2865666fdc839..aaf94657a8b8d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -2,18 +2,25 @@ Module: time */ -// FIXME: Document what these functions do - #[abi = "cdecl"] native mod rustrt { fn get_time(&sec: u32, &usec: u32); - fn nano_time(&ns: u64); + fn precise_time_ns(&ns: u64); } -/* Type: timeval */ +/* +Type: timeval + +A record specifying a time value in seconds and microseconds. +*/ type timeval = {sec: u32, usec: u32}; -/* Function: get_time */ +/* +Function: get_time + +Returns the current time as a `timeval` containing the seconds and +microseconds since 1970-01-01T00:00:00Z. +*/ fn get_time() -> timeval { let sec = 0u32; let usec = 0u32; @@ -21,10 +28,67 @@ fn get_time() -> timeval { ret {sec: sec, usec: usec}; } -/* Function: precise_time_ns */ -fn precise_time_ns() -> u64 { let ns = 0u64; rustrt::nano_time(ns); ret ns; } +/* +Function: precise_time_ns + +Returns the current value of a high-resolution performance counter +in nanoseconds since an unspecified epoch. +*/ +fn precise_time_ns() -> u64 { let ns = 0u64; rustrt::precise_time_ns(ns); ns } + +/* +Function: precise_time_s -/* Function: precise_time_s */ +Returns the current value of a high-resolution performance counter +in seconds since an unspecified epoch. +*/ fn precise_time_s() -> float { ret (precise_time_ns() as float) / 1000000000.; } + +#[cfg(test)] +mod tests { + import task; + + #[test] + fn test_get_time() { + const some_recent_date: u32 = 1325376000u32; // 2012-01-01T00:00:00Z + const some_future_date: u32 = 1577836800u32; // 2020-01-01T00:00:00Z + + let tv1 = get_time(); + log(debug, "tv1=" + uint::str(tv1.sec as uint) + " sec + " + + uint::str(tv1.usec as uint) + " usec"); + + assert tv1.sec > some_recent_date; + assert tv1.usec < 1000000u32; + + let tv2 = get_time(); + log(debug, "tv2=" + uint::str(tv2.sec as uint) + " sec + " + + uint::str(tv2.usec as uint) + " usec"); + + assert tv2.sec >= tv1.sec; + assert tv2.sec < some_future_date; + assert tv2.usec < 1000000u32; + if tv2.sec == tv1.sec { + assert tv2.usec >= tv1.usec; + } + } + + #[test] + fn test_precise_time() { + let s0 = precise_time_s(); + let ns1 = precise_time_ns(); + + log(debug, "s0=" + float::to_str(s0, 9u) + " sec"); + assert s0 > 0.; + let ns0 = (s0 * 1000000000.) as u64; + log(debug, "ns0=" + u64::str(ns0) + " ns"); + + log(debug, "ns1=" + u64::str(ns1) + " ns"); + assert ns1 >= ns0; + + let ns2 = precise_time_ns(); + log(debug, "ns2=" + u64::str(ns2) + " ns"); + assert ns2 >= ns1; + } +} diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index ecc73204f29c8..6c0cd5e5fc0c0 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -393,18 +393,21 @@ rust_ptr_eq(type_desc *t, rust_box *a, rust_box *b) { #if defined(__WIN32__) extern "C" CDECL void get_time(uint32_t *sec, uint32_t *usec) { - rust_task *task = rust_task_thread::get_task(); - SYSTEMTIME systemTime; FILETIME fileTime; - GetSystemTime(&systemTime); - if (!SystemTimeToFileTime(&systemTime, &fileTime)) { - task->fail(); - return; - } + GetSystemTimeAsFileTime(&fileTime); + + // A FILETIME contains a 64-bit value representing the number of + // hectonanosecond (100-nanosecond) intervals since 1601-01-01T00:00:00Z. + // http://support.microsoft.com/kb/167296/en-us + ULARGE_INTEGER ul; + ul.LowPart = fileTime.dwLowDateTime; + ul.HighPart = fileTime.dwHighDateTime; + uint64_t ns_since_1601 = ul.QuadPart / 10; - // FIXME: This is probably completely wrong. - *sec = fileTime.dwHighDateTime; - *usec = fileTime.dwLowDateTime; + const uint64_t NANOSECONDS_FROM_1601_TO_1970 = 11644473600000000u; + uint64_t ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970; + *sec = ns_since_1970 / 1000000; + *usec = ns_since_1970 % 1000000; } #else extern "C" CDECL void @@ -417,7 +420,7 @@ get_time(uint32_t *sec, uint32_t *usec) { #endif extern "C" CDECL void -nano_time(uint64_t *ns) { +precise_time_ns(uint64_t *ns) { timer t; *ns = t.time_ns(); } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index d4fbc0b90bd87..5b62d606917f5 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -13,10 +13,10 @@ get_port_id get_task_id get_time last_os_error -nano_time new_port new_task port_recv +precise_time_ns rust_port_select rand_free rand_new