Skip to content

Convert some C functions to rust functions #11208

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 1 commit into from
Dec 31, 2013
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
106 changes: 96 additions & 10 deletions src/libextra/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,16 @@

use std::io::Reader;
use std::io::mem::BufReader;
use std::libc;
use std::num;
use std::str;

static NSEC_PER_SEC: i32 = 1_000_000_000_i32;

pub mod rustrt {
mod rustrt {
use super::Tm;

extern {
pub fn rust_get_time(sec: &mut i64, nsec: &mut i32);
pub fn rust_precise_time_ns(ns: &mut u64);
pub fn rust_tzset();
pub fn rust_gmtime(sec: i64, nsec: i32, result: &mut Tm);
pub fn rust_localtime(sec: i64, nsec: i32, result: &mut Tm);
Expand All @@ -31,6 +30,31 @@ pub mod rustrt {
}
}

#[cfg(unix, not(target_os = "macos"))]
mod imp {
use std::libc::{c_int, timespec};

// Apparently android provides this in some other library?
#[cfg(not(target_os = "android"))]
#[link(name = "rt")]
extern {}

extern {
pub fn clock_gettime(clk_id: c_int, tp: *mut timespec) -> c_int;
}

}
#[cfg(target_os = "macos")]
mod imp {
use std::libc::{timeval, timezone, c_int, mach_timebase_info};

extern {
pub fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int;
pub fn mach_absolute_time() -> u64;
pub fn mach_timebase_info(info: *mut mach_timebase_info) -> c_int;
}
}

/// A record specifying a time value in seconds and nanoseconds.


Expand Down Expand Up @@ -64,11 +88,45 @@ impl Ord for Timespec {
*/
pub fn get_time() -> Timespec {
unsafe {
let mut sec = 0i64;
let mut nsec = 0i32;
rustrt::rust_get_time(&mut sec, &mut nsec);
let (sec, nsec) = os_get_time();
return Timespec::new(sec, nsec);
}

#[cfg(windows)]
unsafe fn os_get_time() -> (i64, i32) {
static NANOSECONDS_FROM_1601_TO_1970: u64 = 11644473600000000;

let mut time = libc::FILETIME {
dwLowDateTime: 0,
dwHighDateTime: 0,
};
libc::GetSystemTimeAsFileTime(&mut time);

// 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
let ns_since_1601 = ((time.dwHighDateTime as u64 << 32) |
(time.dwLowDateTime as u64 << 0)) / 10;
let ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970;

((ns_since_1970 / 1000000) as i64,
((ns_since_1970 % 1000000) * 1000) as i32)
}

#[cfg(target_os = "macos")]
unsafe fn os_get_time() -> (i64, i32) {
use std::ptr;
let mut tv = libc::timeval { tv_sec: 0, tv_usec: 0 };
imp::gettimeofday(&mut tv, ptr::mut_null());
(tv.tv_sec as i64, tv.tv_usec * 1000)
}

#[cfg(not(target_os = "macos"), not(windows))]
unsafe fn os_get_time() -> (i64, i32) {
let mut tv = libc::timespec { tv_sec: 0, tv_nsec: 0 };
imp::clock_gettime(libc::CLOCK_REALTIME, &mut tv);
(tv.tv_sec as i64, tv.tv_nsec as i32)
}
}


Expand All @@ -77,10 +135,38 @@ pub fn get_time() -> Timespec {
* in nanoseconds since an unspecified epoch.
*/
pub fn precise_time_ns() -> u64 {
unsafe {
let mut ns = 0u64;
rustrt::rust_precise_time_ns(&mut ns);
ns
return os_precise_time_ns();

#[cfg(windows)]
fn os_precise_time_ns() -> u64 {
let mut ticks_per_s = 0;
assert_eq!(unsafe {
libc::QueryPerformanceFrequency(&mut ticks_per_s)
}, 1);
let ticks_per_s = if ticks_per_s == 0 {1} else {ticks_per_s};
let mut ticks = 0;
assert_eq!(unsafe {
libc::QueryPerformanceCounter(&mut ticks)
}, 1);

return (ticks as u64 * 1000000000) / (ticks_per_s as 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);
}

#[cfg(not(windows), not(target_os = "macos"))]
fn os_precise_time_ns() -> u64 {
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
unsafe {
imp::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts);
}
return (ts.tv_sec as u64) * 1000000000 + (ts.tv_nsec as u64)
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/librustuv/uvll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,10 @@ extern {
#[link(name = "pthread")]
extern {}

#[cfg(target_os = "linux")]
#[link(name = "rt")]
extern {}

#[cfg(target_os = "win32")]
#[link(name = "ws2_32")]
#[link(name = "psapi")]
Expand Down
Loading