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/windows | |
| 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/windows')
| -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 |
4 files changed, 31 insertions, 23 deletions
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); } |
