Merge pull request #1865 from cpeterso/time

Fix Windows system time conversion for get_time()
This commit is contained in:
Brian Anderson 2012-02-18 13:13:00 -08:00
commit 9e8fc364b0
3 changed files with 87 additions and 20 deletions

View File

@ -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
/* Function: precise_time_s */
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
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;
}
}

View File

@ -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);
// FIXME: This is probably completely wrong.
*sec = fileTime.dwHighDateTime;
*usec = fileTime.dwLowDateTime;
// 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;
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();
}

View File

@ -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