Skip to content

Fix Windows system time conversion for get_time() #1865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 18, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 72 additions & 8 deletions src/libstd/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,93 @@
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;
rustrt::get_time(sec, usec);
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;
}
}
25 changes: 14 additions & 11 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down