diff options
| author | Kelvin Ly <kelvin.ly1618@gmail.com> | 2015-05-14 20:45:18 -0400 |
|---|---|---|
| committer | Kelvin Ly <kelvin.ly1618@gmail.com> | 2015-05-14 20:45:18 -0400 |
| commit | 507f8b8d942f17452c16876a02bef9e1bc15d028 (patch) | |
| tree | ec1924346cc4537d10a5b55eaca4f1620436f87e /src/libstd/sys | |
| parent | 6e9e76ae5fe6a3104c265b43dcb5705b5ccd2743 (diff) | |
| parent | 571f371b3fce3e023fb1b41a1682de260c943222 (diff) | |
| download | rust-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.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/unix/time.rs | 30 | ||||
| -rw-r--r-- | src/libstd/sys/windows/condvar.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/windows/mod.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/windows/thread.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys/windows/time.rs | 20 |
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); } |
