about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorKelvin Ly <kelvin.ly1618@gmail.com>2015-05-14 20:45:18 -0400
committerKelvin Ly <kelvin.ly1618@gmail.com>2015-05-14 20:45:18 -0400
commit507f8b8d942f17452c16876a02bef9e1bc15d028 (patch)
treeec1924346cc4537d10a5b55eaca4f1620436f87e /src/libstd/sys
parent6e9e76ae5fe6a3104c265b43dcb5705b5ccd2743 (diff)
parent571f371b3fce3e023fb1b41a1682de260c943222 (diff)
downloadrust-507f8b8d942f17452c16876a02bef9e1bc15d028.tar.gz
rust-507f8b8d942f17452c16876a02bef9e1bc15d028.zip
Fix merge conflict and also add markdown formatting
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/condvar.rs22
-rw-r--r--src/libstd/sys/unix/thread.rs9
-rw-r--r--src/libstd/sys/unix/time.rs30
-rw-r--r--src/libstd/sys/windows/condvar.rs2
-rw-r--r--src/libstd/sys/windows/mod.rs22
-rw-r--r--src/libstd/sys/windows/thread.rs10
-rw-r--r--src/libstd/sys/windows/time.rs20
7 files changed, 54 insertions, 61 deletions
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index ed6382e000a..29a13cc6be7 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -57,25 +57,20 @@ impl Condvar {
     // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
     // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
-        if dur <= Duration::zero() {
-            return false;
-        }
-
-        // First, figure out what time it currently is, in both system and stable time.
-        // pthread_cond_timedwait uses system time, but we want to report timeout based on stable
-        // time.
+        // First, figure out what time it currently is, in both system and
+        // stable time.  pthread_cond_timedwait uses system time, but we want to
+        // report timeout based on stable time.
         let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
         let stable_now = time::SteadyTime::now();
         let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut());
         debug_assert_eq!(r, 0);
 
-        let seconds = dur.num_seconds() as libc::time_t;
+        let seconds = dur.secs() as libc::time_t;
         let timeout = match sys_now.tv_sec.checked_add(seconds) {
             Some(sec) => {
                 libc::timespec {
                     tv_sec: sec,
-                    tv_nsec: (dur - Duration::seconds(dur.num_seconds()))
-                        .num_nanoseconds().unwrap() as libc::c_long,
+                    tv_nsec: dur.extra_nanos() as libc::c_long,
                 }
             }
             None => {
@@ -87,11 +82,12 @@ impl Condvar {
         };
 
         // And wait!
-        let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), &timeout);
+        let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
+                                            &timeout);
         debug_assert!(r == libc::ETIMEDOUT || r == 0);
 
-        // ETIMEDOUT is not a totally reliable method of determining timeout due to clock shifts,
-        // so do the check ourselves
+        // ETIMEDOUT is not a totally reliable method of determining timeout due
+        // to clock shifts, so do the check ourselves
         &time::SteadyTime::now() - &stable_now < dur
     }
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index cfab9d1c51a..0cb5a06e6b6 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -129,14 +129,9 @@ impl Thread {
     }
 
     pub fn sleep(dur: Duration) {
-        if dur < Duration::zero() {
-            return Thread::yield_now()
-        }
-        let seconds = dur.num_seconds();
-        let ns = dur - Duration::seconds(seconds);
         let mut ts = libc::timespec {
-            tv_sec: seconds as libc::time_t,
-            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
+            tv_sec: dur.secs() as libc::time_t,
+            tv_nsec: dur.extra_nanos() as libc::c_long,
         };
 
         // If we're awoken with a signal then the return value will be -1 and
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index f59eb2c0301..16dfd3eebd0 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -10,12 +10,15 @@
 
 pub use self::inner::SteadyTime;
 
+const NSEC_PER_SEC: u64 = 1_000_000_000;
+
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 mod inner {
     use libc;
     use time::Duration;
     use ops::Sub;
     use sync::{Once, ONCE_INIT};
+    use super::NSEC_PER_SEC;
 
     pub struct SteadyTime {
         t: u64
@@ -32,11 +35,6 @@ mod inner {
                 t: unsafe { mach_absolute_time() },
             }
         }
-
-        pub fn ns(&self) -> u64 {
-            let info = info();
-            self.t * info.numer as u64 / info.denom as u64
-        }
     }
 
     fn info() -> &'static libc::mach_timebase_info {
@@ -59,8 +57,9 @@ mod inner {
 
         fn sub(self, other: &SteadyTime) -> Duration {
             let info = info();
-            let diff = self.t as i64 - other.t as i64;
-            Duration::nanoseconds(diff * info.numer as i64 / info.denom as i64)
+            let diff = self.t as u64 - other.t as u64;
+            let nanos = diff * info.numer as u64 / info.denom as u64;
+            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
         }
     }
 }
@@ -70,8 +69,7 @@ mod inner {
     use libc;
     use time::Duration;
     use ops::Sub;
-
-    const NSEC_PER_SEC: i64 = 1_000_000_000;
+    use super::NSEC_PER_SEC;
 
     pub struct SteadyTime {
         t: libc::timespec,
@@ -104,10 +102,6 @@ mod inner {
             }
             t
         }
-
-        pub fn ns(&self) -> u64 {
-            self.t.tv_sec as u64 * NSEC_PER_SEC as u64 + self.t.tv_nsec as u64
-        }
     }
 
     impl<'a> Sub for &'a SteadyTime {
@@ -115,12 +109,12 @@ mod inner {
 
         fn sub(self, other: &SteadyTime) -> Duration {
             if self.t.tv_nsec >= other.t.tv_nsec {
-                Duration::seconds(self.t.tv_sec as i64 - other.t.tv_sec as i64) +
-                    Duration::nanoseconds(self.t.tv_nsec as i64 - other.t.tv_nsec as i64)
+                Duration::new(self.t.tv_sec as u64 - other.t.tv_sec as u64,
+                              self.t.tv_nsec as u32 - other.t.tv_nsec as u32)
             } else {
-                Duration::seconds(self.t.tv_sec as i64 - 1 - other.t.tv_sec as i64) +
-                    Duration::nanoseconds(self.t.tv_nsec as i64 + NSEC_PER_SEC -
-                                          other.t.tv_nsec as i64)
+                Duration::new(self.t.tv_sec as u64 - 1 - other.t.tv_sec as u64,
+                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
+                                          other.t.tv_nsec as u32)
             }
         }
     }
diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs
index 67552255fdb..8bb2326e4d6 100644
--- a/src/libstd/sys/windows/condvar.rs
+++ b/src/libstd/sys/windows/condvar.rs
@@ -42,7 +42,7 @@ impl Condvar {
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         let r = ffi::SleepConditionVariableSRW(self.inner.get(),
                                                mutex::raw(mutex),
-                                               dur.num_milliseconds() as DWORD,
+                                               super::dur2timeout(dur),
                                                0);
         if r == 0 {
             const ERROR_TIMEOUT: DWORD = 0x5B4;
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 4c30f0f8660..6b7bff2c1c6 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -20,6 +20,7 @@ use libc;
 use num::Zero;
 use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
+use time::Duration;
 
 pub mod backtrace;
 pub mod c;
@@ -151,6 +152,27 @@ fn cvt<I: PartialEq + Zero>(i: I) -> io::Result<I> {
     }
 }
 
+fn dur2timeout(dur: Duration) -> libc::DWORD {
+    // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the
+    // timeouts in windows APIs are typically u32 milliseconds. To translate, we
+    // have two pieces to take care of:
+    //
+    // * Nanosecond precision is rounded up
+    // * Greater than u32::MAX milliseconds (50 days) is rounded up to INFINITE
+    //   (never time out).
+    dur.secs().checked_mul(1000).and_then(|ms| {
+        ms.checked_add((dur.extra_nanos() as u64) / 1_000_000)
+    }).and_then(|ms| {
+        ms.checked_add(if dur.extra_nanos() % 1_000_000 > 0 {1} else {0})
+    }).map(|ms| {
+        if ms > <libc::DWORD>::max_value() as u64 {
+            libc::INFINITE
+        } else {
+            ms as libc::DWORD
+        }
+    }).unwrap_or(libc::INFINITE)
+}
+
 fn ms_to_filetime(ms: u64) -> libc::FILETIME {
     // A FILETIME is a count of 100 nanosecond intervals, so we multiply by
     // 10000 b/c there are 10000 intervals in 1 ms
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index 797f45f8702..50dfee4ab10 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -80,15 +80,7 @@ impl Thread {
 
     pub fn sleep(dur: Duration) {
         unsafe {
-            if dur < Duration::zero() {
-                return Thread::yield_now()
-            }
-            let ms = dur.num_milliseconds();
-            // if we have a fractional number of milliseconds then add an extra
-            // millisecond to sleep for
-            let extra = dur - Duration::milliseconds(ms);
-            let ms = ms + if extra.is_zero() {0} else {1};
-            c::Sleep(ms as DWORD);
+            c::Sleep(super::dur2timeout(dur))
         }
     }
 }
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index 209460df10b..e64df54a0fa 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -12,7 +12,7 @@ use ops::Sub;
 use time::Duration;
 use sync::{Once, ONCE_INIT};
 
-const NANOS_PER_SEC: i64 = 1_000_000_000;
+const NANOS_PER_SEC: u64 = 1_000_000_000;
 
 pub struct SteadyTime {
     t: libc::LARGE_INTEGER,
@@ -24,10 +24,6 @@ impl SteadyTime {
         unsafe { libc::QueryPerformanceCounter(&mut t.t); }
         t
     }
-
-    pub fn ns(&self) -> u64 {
-        mul_div_i64(self.t as i64, NANOS_PER_SEC, frequency() as i64) as u64
-    }
 }
 
 fn frequency() -> libc::LARGE_INTEGER {
@@ -46,15 +42,16 @@ impl<'a> Sub for &'a SteadyTime {
     type Output = Duration;
 
     fn sub(self, other: &SteadyTime) -> Duration {
-        let diff = self.t as i64 - other.t as i64;
-        Duration::nanoseconds(mul_div_i64(diff, NANOS_PER_SEC, frequency() as i64))
+        let diff = self.t as u64 - other.t as u64;
+        let nanos = mul_div_u64(diff, NANOS_PER_SEC, frequency() as u64);
+        Duration::new(nanos / NANOS_PER_SEC, (nanos % NANOS_PER_SEC) as u32)
     }
 }
 
 // Computes (value*numer)/denom without overflow, as long as both
 // (numer*denom) and the overall result fit into i64 (which is the case
 // for our time conversions).
-fn mul_div_i64(value: i64, numer: i64, denom: i64) -> i64 {
+fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 {
     let q = value / denom;
     let r = value % denom;
     // Decompose value as (value/denom*denom + value%denom),
@@ -65,9 +62,6 @@ fn mul_div_i64(value: i64, numer: i64, denom: i64) -> i64 {
 
 #[test]
 fn test_muldiv() {
-    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000, 1_000_000),  1_000_000_000_001_000);
-    assert_eq!(mul_div_i64(-1_000_000_000_001, 1_000_000_000, 1_000_000), -1_000_000_000_001_000);
-    assert_eq!(mul_div_i64(-1_000_000_000_001,-1_000_000_000, 1_000_000),  1_000_000_000_001_000);
-    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000,-1_000_000), -1_000_000_000_001_000);
-    assert_eq!(mul_div_i64( 1_000_000_000_001,-1_000_000_000,-1_000_000),  1_000_000_000_001_000);
+    assert_eq!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000),
+               1_000_000_000_001_000);
 }