]> git.lizzy.rs Git - rust.git/commitdiff
Convert some C functions to rust functions
authorAlex Crichton <alex@alexcrichton.com>
Mon, 30 Dec 2013 04:09:40 +0000 (20:09 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 30 Dec 2013 22:35:55 +0000 (14:35 -0800)
Right now on linux, an empty executable with LTO still depends on librt becaues
of the clock_gettime function in rust_builtin.o, but this commit moves this
dependency into a rust function which is subject to elimination via LTO.

At the same time, this also drops libstd's dependency on librt on unices that
are not OSX because the library is only used by extra::time (and now the
dependency is listed in that module instead).

src/libextra/time.rs
src/librustuv/uvll.rs
src/libstd/libc.rs
src/libstd/rtdeps.rs
src/rt/rust_builtin.c

index 6204f9f4ce0b11c833d69fd2d86e5cbf87f2d84f..23c81c6fce529863c55834ad86f1710b0dcb0fed 100644 (file)
 
 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);
@@ -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.
 
 
@@ -64,11 +88,45 @@ fn lt(&self, other: &Timespec) -> bool {
  */
 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)
+    }
 }
 
 
@@ -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)
     }
 }
 
index dfe67f050ec9f30f3b275e1fb6ca29fd55421144..eefccf05a542c87ecc1b0b3037f184898e994a45 100644 (file)
@@ -739,6 +739,10 @@ pub fn uv_signal_start(h: *uv_signal_t, cb: uv_signal_cb,
 #[link(name = "pthread")]
 extern {}
 
+#[cfg(target_os = "linux")]
+#[link(name = "rt")]
+extern {}
+
 #[cfg(target_os = "win32")]
 #[link(name = "ws2_32")]
 #[link(name = "psapi")]
index 2696e27c373174f841dd1416cde375b904ab5064..fdfc28d9d10c8571141255777493cd39ef48bd62 100644 (file)
@@ -226,7 +226,8 @@ pub mod os {
         pub mod common {
             pub mod posix01 {
                 use libc::types::common::c95::{c_void};
-                use libc::types::os::arch::c95::{c_char, c_ulong, size_t};
+                use libc::types::os::arch::c95::{c_char, c_ulong, size_t,
+                                                 time_t, suseconds_t, c_long};
 
                 pub type pthread_t = c_ulong;
 
@@ -241,6 +242,18 @@ pub struct glob_t {
                     __unused4: *c_void,
                     __unused5: *c_void,
                 }
+
+                pub struct timeval {
+                    tv_sec: time_t,
+                    tv_usec: suseconds_t,
+                }
+
+                pub struct timespec {
+                    tv_sec: time_t,
+                    tv_nsec: c_long,
+                }
+
+                pub enum timezone {}
             }
             pub mod bsd44 {
                 pub type socklen_t = u32;
@@ -298,6 +311,7 @@ pub mod c95 {
                 pub type ptrdiff_t = i32;
                 pub type clock_t = i32;
                 pub type time_t = i32;
+                pub type suseconds_t = i32;
                 pub type wchar_t = i32;
             }
             pub mod c99 {
@@ -481,6 +495,7 @@ pub mod c95 {
                 pub type ptrdiff_t = i64;
                 pub type clock_t = i64;
                 pub type time_t = i64;
+                pub type suseconds_t = i64;
                 pub type wchar_t = i32;
             }
             pub mod c99 {
@@ -553,7 +568,8 @@ pub mod os {
         pub mod common {
             pub mod posix01 {
                 use libc::types::common::c95::{c_void};
-                use libc::types::os::arch::c95::{c_char, c_int, size_t};
+                use libc::types::os::arch::c95::{c_char, c_int, size_t,
+                                                 time_t, suseconds_t, c_long};
                 use libc::types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
@@ -573,6 +589,18 @@ pub struct glob_t {
                     __unused7: *c_void,
                     __unused8: *c_void,
                 }
+
+                pub struct timeval {
+                    tv_sec: time_t,
+                    tv_usec: suseconds_t,
+                }
+
+                pub struct timespec {
+                    tv_sec: time_t,
+                    tv_nsec: c_long,
+                }
+
+                pub enum timezone {}
             }
             pub mod bsd44 {
                 pub type socklen_t = u32;
@@ -633,6 +661,7 @@ pub mod c95 {
                 pub type ptrdiff_t = i64;
                 pub type clock_t = i32;
                 pub type time_t = i64;
+                pub type suseconds_t = i64;
                 pub type wchar_t = i32;
             }
             pub mod c99 {
@@ -709,7 +738,8 @@ pub mod extra {
     pub mod os {
         pub mod common {
             pub mod posix01 {
-                use libc::types::os::arch::c95::c_short;
+                use libc::types::os::arch::c95::{c_short, time_t, suseconds_t,
+                                                 c_long};
                 use libc::types::os::arch::extra::{int64, time64_t};
                 use libc::types::os::arch::posix88::{dev_t, ino_t};
                 use libc::types::os::arch::posix88::mode_t;
@@ -735,6 +765,18 @@ pub struct utimbuf {
                     actime: time64_t,
                     modtime: time64_t,
                 }
+
+                pub struct timeval {
+                    tv_sec: time_t,
+                    tv_usec: suseconds_t,
+                }
+
+                pub struct timespec {
+                    tv_sec: time_t,
+                    tv_nsec: c_long,
+                }
+
+                pub enum timezone {}
             }
 
             pub mod bsd44 {
@@ -807,6 +849,11 @@ pub mod c95 {
                 #[cfg(target_arch = "x86_64")]
                 pub type time_t = i64;
 
+                #[cfg(target_arch = "x86")]
+                pub type suseconds_t = i32;
+                #[cfg(target_arch = "x86_64")]
+                pub type suseconds_t = i64;
+
                 pub type wchar_t = u16;
             }
 
@@ -983,6 +1030,13 @@ pub struct OVERLAPPED {
                 }
 
                 pub type LPOVERLAPPED = *mut OVERLAPPED;
+
+                pub struct FILETIME {
+                    dwLowDateTime: DWORD,
+                    dwHighDateTime: DWORD,
+                }
+
+                pub type LPFILETIME = *mut FILETIME;
             }
         }
     }
@@ -991,8 +1045,9 @@ pub struct OVERLAPPED {
     pub mod os {
         pub mod common {
             pub mod posix01 {
-                use libc::types::common::c95::{c_void};
-                use libc::types::os::arch::c95::{c_char, c_int, size_t};
+                use libc::types::common::c95::c_void;
+                use libc::types::os::arch::c95::{c_char, c_int, size_t,
+                                                 time_t, suseconds_t, c_long};
                 use libc::types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
@@ -1012,6 +1067,18 @@ pub struct glob_t {
                     __unused7: *c_void,
                     __unused8: *c_void,
                 }
+
+                pub struct timeval {
+                    tv_sec: time_t,
+                    tv_usec: suseconds_t,
+                }
+
+                pub struct timespec {
+                    tv_sec: time_t,
+                    tv_nsec: c_long,
+                }
+
+                pub enum timezone {}
             }
 
             pub mod bsd44 {
@@ -1075,6 +1142,7 @@ pub mod c95 {
                 pub type ptrdiff_t = i32;
                 pub type clock_t = u32;
                 pub type time_t = i32;
+                pub type suseconds_t = i32;
                 pub type wchar_t = i32;
             }
             pub mod c99 {
@@ -1144,6 +1212,12 @@ pub mod posix08 {
             pub mod bsd44 {
             }
             pub mod extra {
+                pub struct mach_timebase_info {
+                    numer: u32,
+                    denom: u32,
+                }
+
+                pub type mach_timebase_info_data_t = mach_timebase_info;
             }
         }
 
@@ -1165,6 +1239,7 @@ pub mod c95 {
                 pub type ptrdiff_t = i64;
                 pub type clock_t = u64;
                 pub type time_t = i64;
+                pub type suseconds_t = i32;
                 pub type wchar_t = i32;
             }
             pub mod c99 {
@@ -1235,6 +1310,12 @@ pub mod posix08 {
             pub mod bsd44 {
             }
             pub mod extra {
+                pub struct mach_timebase_info {
+                    numer: u32,
+                    denom: u32,
+                }
+
+                pub type mach_timebase_info_data_t = mach_timebase_info;
             }
         }
     }
@@ -2047,6 +2128,9 @@ pub mod posix01 {
 
             pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
             pub static PTHREAD_CREATE_DETACHED: c_int = 1;
+
+            pub static CLOCK_REALTIME: c_int = 0;
+            pub static CLOCK_MONOTONIC: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -2467,6 +2551,9 @@ pub mod posix01 {
 
             pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
             pub static PTHREAD_CREATE_DETACHED: c_int = 1;
+
+            pub static CLOCK_REALTIME: c_int = 0;
+            pub static CLOCK_MONOTONIC: c_int = 4;
         }
         pub mod posix08 {
         }
@@ -3609,8 +3696,7 @@ pub fn send(socket: SOCKET, buf: *mut c_void, len: c_int,
     #[cfg(target_os = "freebsd")]
     pub mod bsd44 {
         use libc::types::common::c95::{c_void};
-        use libc::types::os::arch::c95::{c_char, c_uchar, c_int, c_uint,
-                                         size_t};
+        use libc::types::os::arch::c95::{c_char, c_uchar, c_int, c_uint, size_t};
 
         extern {
             pub fn sysctl(name: *c_int,
@@ -3694,7 +3780,7 @@ pub mod kernel32 {
                                                LPMEMORY_BASIC_INFORMATION,
                                                LPSYSTEM_INFO};
             use libc::types::os::arch::extra::{HANDLE, LPHANDLE, LARGE_INTEGER,
-                                               PLARGE_INTEGER};
+                                               PLARGE_INTEGER, LPFILETIME};
 
             extern "system" {
                 pub fn GetEnvironmentVariableW(n: LPCWSTR,
@@ -3838,6 +3924,14 @@ pub fn SetFilePointerEx(hFile: HANDLE,
                                         lpNewFilePointer: PLARGE_INTEGER,
                                         dwMoveMethod: DWORD) -> BOOL;
                 pub fn SetEndOfFile(hFile: HANDLE) -> BOOL;
+
+                pub fn GetSystemTimeAsFileTime(
+                            lpSystemTimeAsFileTime: LPFILETIME);
+
+                pub fn QueryPerformanceFrequency(
+                            lpFrequency: *mut LARGE_INTEGER) -> BOOL;
+                pub fn QueryPerformanceCounter(
+                            lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL;
             }
         }
 
index 1ecfc1f25d02e47e9f278468d717b8633cf685ca..045cdf574f62ff37727d1af9353f80a02ede0edb 100644 (file)
@@ -22,7 +22,6 @@
 // On linux librt and libdl are indirect dependencies via rustrt,
 // and binutils 2.22+ won't add them automatically
 #[cfg(target_os = "linux")]
-#[link(name = "rt")]
 #[link(name = "dl")]
 #[link(name = "m")]
 #[link(name = "pthread")]
@@ -36,7 +35,6 @@
 
 #[cfg(target_os = "freebsd")]
 #[link(name = "execinfo")]
-#[link(name = "rt")]
 #[link(name = "pthread")]
 extern {}
 
index f14554fd65bf8d73b7093d5efec7a5c2fd041d6b..6de5f80829003602f3ce7c8e0004b9e514c553b1 100644 (file)
@@ -127,73 +127,6 @@ rust_list_dir_wfd_fp_buf(void* wfd) {
 }
 #endif
 
-#if defined(__WIN32__)
-void
-rust_get_time(int64_t *sec, int32_t *nsec) {
-    FILETIME fileTime;
-    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;
-
-    const uint64_t NANOSECONDS_FROM_1601_TO_1970 = 11644473600000000ull;
-    uint64_t ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970;
-    *sec = ns_since_1970 / 1000000;
-    *nsec = (ns_since_1970 % 1000000) * 1000;
-}
-#else
-void
-rust_get_time(int64_t *sec, int32_t *nsec) {
-#ifdef __APPLE__
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    *sec = tv.tv_sec;
-    *nsec = tv.tv_usec * 1000;
-#else
-    struct timespec ts;
-    clock_gettime(CLOCK_REALTIME, &ts);
-    *sec = ts.tv_sec;
-    *nsec = ts.tv_nsec;
-#endif
-}
-#endif
-
-const int64_t ns_per_s = 1000000000LL;
-
-void
-rust_precise_time_ns(uint64_t *ns) {
-
-#ifdef __APPLE__
-    uint64_t time = mach_absolute_time();
-    mach_timebase_info_data_t info = {0, 0};
-    if (info.denom == 0) {
-        mach_timebase_info(&info);
-    }
-    uint64_t time_nano = time * (info.numer / info.denom);
-    *ns = time_nano;
-#elif __WIN32__
-    LARGE_INTEGER ticks_per_s;
-    BOOL query_result = QueryPerformanceFrequency(&ticks_per_s);
-    assert(query_result);
-    if (ticks_per_s.QuadPart == 0LL) {
-        ticks_per_s.QuadPart = 1LL;
-    }
-    LARGE_INTEGER ticks;
-    query_result = QueryPerformanceCounter(&ticks);
-    assert(query_result);
-    *ns = (uint64_t)((ticks.QuadPart * ns_per_s) / ticks_per_s.QuadPart);
-#else
-    struct timespec ts;
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    *ns = (uint64_t)(ts.tv_sec * ns_per_s + ts.tv_nsec);
-#endif
-}
-
 typedef struct
 {
     size_t fill;    // in bytes; if zero, heapified