Merge pull request #1865 from cpeterso/time
Fix Windows system time conversion for get_time()
This commit is contained in:
commit
9e8fc364b0
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue