Skip to content
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

Add checked_add method to Instant time type #56490

Merged
merged 4 commits into from
Dec 14, 2018
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
6 changes: 4 additions & 2 deletions src/libstd/sys/cloudabi/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use mem;
use sync::atomic::{AtomicU32, Ordering};
use sys::cloudabi::abi;
use sys::mutex::{self, Mutex};
use sys::time::dur2intervals;
use sys::time::checked_dur2intervals;
use time::Duration;

extern "C" {
Expand Down Expand Up @@ -114,6 +114,8 @@ impl Condvar {

// Call into the kernel to wait on the condition variable.
let condvar = self.condvar.get();
let timeout = checked_dur2intervals(&dur)
.expect("overflow converting duration to nanoseconds");
let subscriptions = [
abi::subscription {
type_: abi::eventtype::CONDVAR,
Expand All @@ -132,7 +134,7 @@ impl Condvar {
union: abi::subscription_union {
clock: abi::subscription_clock {
clock_id: abi::clockid::MONOTONIC,
timeout: dur2intervals(&dur),
timeout,
..mem::zeroed()
},
},
Expand Down
6 changes: 4 additions & 2 deletions src/libstd/sys/cloudabi/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use libc;
use mem;
use ptr;
use sys::cloudabi::abi;
use sys::time::dur2intervals;
use sys::time::checked_dur2intervals;
use sys_common::thread::*;
use time::Duration;

Expand Down Expand Up @@ -70,13 +70,15 @@ impl Thread {
}

pub fn sleep(dur: Duration) {
let timeout = checked_dur2intervals(&dur)
.expect("overflow converting duration to nanoseconds");
unsafe {
let subscription = abi::subscription {
type_: abi::eventtype::CLOCK,
union: abi::subscription_union {
clock: abi::subscription_clock {
clock_id: abi::clockid::MONOTONIC,
timeout: dur2intervals(&dur),
timeout,
..mem::zeroed()
},
},
Expand Down
52 changes: 18 additions & 34 deletions src/libstd/sys/cloudabi/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,10 @@ pub struct Instant {
t: abi::timestamp,
}

fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
dur.as_secs()
.checked_mul(NSEC_PER_SEC)
.and_then(|nanos| nanos.checked_add(dur.subsec_nanos() as abi::timestamp))
}

pub fn dur2intervals(dur: &Duration) -> abi::timestamp {
checked_dur2intervals(dur)
.expect("overflow converting duration to nanoseconds")
.checked_mul(NSEC_PER_SEC)?
.checked_add(dur.subsec_nanos() as abi::timestamp)
}

impl Instant {
Expand All @@ -47,20 +42,16 @@ impl Instant {
Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)
}

pub fn add_duration(&self, other: &Duration) -> Instant {
Instant {
t: self.t
.checked_add(dur2intervals(other))
.expect("overflow when adding duration to instant"),
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant {
t: self.t.checked_add(checked_dur2intervals(other)?)?,
})
}

pub fn sub_duration(&self, other: &Duration) -> Instant {
Instant {
t: self.t
.checked_sub(dur2intervals(other))
.expect("overflow when subtracting duration from instant"),
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant {
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
})
}
}

Expand Down Expand Up @@ -95,23 +86,16 @@ impl SystemTime {
}
}

pub fn add_duration(&self, other: &Duration) -> SystemTime {
self.checked_add_duration(other)
.expect("overflow when adding duration to instant")
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
checked_dur2intervals(other)
.and_then(|d| self.t.checked_add(d))
.map(|t| SystemTime {t})
Some(SystemTime {
t: self.t.checked_add(checked_dur2intervals(other)?)?,
})
}

pub fn sub_duration(&self, other: &Duration) -> SystemTime {
SystemTime {
t: self.t
.checked_sub(dur2intervals(other))
.expect("overflow when subtracting duration from instant"),
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime {
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
})
}
}

Expand Down
34 changes: 12 additions & 22 deletions src/libstd/sys/redox/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ impl Timespec {
}
}

fn add_duration(&self, other: &Duration) -> Timespec {
self.checked_add_duration(other).expect("overflow when adding duration to time")
}

fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = other
.as_secs()
Expand All @@ -67,27 +63,25 @@ impl Timespec {
})
}

fn sub_duration(&self, other: &Duration) -> Timespec {
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = other
.as_secs()
.try_into() // <- target type would be `i64`
.ok()
.and_then(|secs| self.t.tv_sec.checked_sub(secs))
.expect("overflow when subtracting duration from time");
.and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

// Similar to above, nanos can't overflow.
let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
if nsec < 0 {
nsec += NSEC_PER_SEC as i32;
secs = secs.checked_sub(1).expect("overflow when subtracting \
duration from time");
secs = secs.checked_sub(1)?;
}
Timespec {
Some(Timespec {
t: syscall::TimeSpec {
tv_sec: secs,
tv_nsec: nsec as i32,
},
}
})
}
}

Expand Down Expand Up @@ -150,12 +144,12 @@ impl Instant {
})
}

pub fn add_duration(&self, other: &Duration) -> Instant {
Instant { t: self.t.add_duration(other) }
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_add_duration(other)? })
}

pub fn sub_duration(&self, other: &Duration) -> Instant {
Instant { t: self.t.sub_duration(other) }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_sub_duration(other)? })
}
}

Expand All @@ -178,16 +172,12 @@ impl SystemTime {
self.t.sub_timespec(&other.t)
}

pub fn add_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.add_duration(other) }
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
self.t.checked_add_duration(other).map(|t| SystemTime { t })
Some(SystemTime { t: self.t.checked_add_duration(other)? })
}

pub fn sub_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.sub_duration(other) }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_sub_duration(other)? })
}
}

Expand Down
18 changes: 7 additions & 11 deletions src/libstd/sys/sgx/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ impl Instant {
self.0 - other.0
}

pub fn add_duration(&self, other: &Duration) -> Instant {
Instant(self.0 + *other)
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant(self.0.checked_add(*other)?))
}

pub fn sub_duration(&self, other: &Duration) -> Instant {
Instant(self.0 - *other)
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant(self.0.checked_sub(*other)?))
}
}

Expand All @@ -47,15 +47,11 @@ impl SystemTime {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
}

pub fn add_duration(&self, other: &Duration) -> SystemTime {
SystemTime(self.0 + *other)
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
self.0.checked_add(*other).map(|d| SystemTime(d))
Some(SystemTime(self.0.checked_add(*other)?))
}

pub fn sub_duration(&self, other: &Duration) -> SystemTime {
SystemTime(self.0 - *other)
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}
72 changes: 28 additions & 44 deletions src/libstd/sys/unix/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ impl Timespec {
}
}

fn add_duration(&self, other: &Duration) -> Timespec {
self.checked_add_duration(other).expect("overflow when adding duration to time")
}

fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = other
.as_secs()
Expand All @@ -68,27 +64,25 @@ impl Timespec {
})
}

fn sub_duration(&self, other: &Duration) -> Timespec {
fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
let mut secs = other
.as_secs()
.try_into() // <- target type would be `libc::time_t`
.ok()
.and_then(|secs| self.t.tv_sec.checked_sub(secs))
.expect("overflow when subtracting duration from time");
.and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

// Similar to above, nanos can't overflow.
let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
if nsec < 0 {
nsec += NSEC_PER_SEC as i32;
secs = secs.checked_sub(1).expect("overflow when subtracting \
duration from time");
secs = secs.checked_sub(1)?;
}
Timespec {
Some(Timespec {
t: libc::timespec {
tv_sec: secs,
tv_nsec: nsec as _,
},
}
})
}
}

Expand Down Expand Up @@ -165,18 +159,16 @@ mod inner {
Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
}

pub fn add_duration(&self, other: &Duration) -> Instant {
Instant {
t: self.t.checked_add(dur2intervals(other))
.expect("overflow when adding duration to instant"),
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant {
t: self.t.checked_add(checked_dur2intervals(other)?)?,
})
}

pub fn sub_duration(&self, other: &Duration) -> Instant {
Instant {
t: self.t.checked_sub(dur2intervals(other))
.expect("overflow when subtracting duration from instant"),
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant {
t: self.t.checked_sub(checked_dur2intervals(other)?)?,
})
}
}

Expand All @@ -199,16 +191,12 @@ mod inner {
self.t.sub_timespec(&other.t)
}

pub fn add_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.add_duration(other) }
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
self.t.checked_add_duration(other).map(|t| SystemTime { t })
Some(SystemTime { t: self.t.checked_add_duration(other)? })
}

pub fn sub_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.sub_duration(other) }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_sub_duration(other)? })
}
}

Expand Down Expand Up @@ -236,12 +224,12 @@ mod inner {
}
}

fn dur2intervals(dur: &Duration) -> u64 {
fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
let nanos = dur.as_secs()
.checked_mul(NSEC_PER_SEC)?
.checked_add(dur.subsec_nanos() as u64)?;
let info = info();
let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
nanos.checked_add(dur.subsec_nanos() as u64)
}).expect("overflow converting duration to nanoseconds");
mul_div_u64(nanos, info.denom as u64, info.numer as u64)
Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
}

fn info() -> &'static libc::mach_timebase_info {
Expand Down Expand Up @@ -299,12 +287,12 @@ mod inner {
})
}

pub fn add_duration(&self, other: &Duration) -> Instant {
Instant { t: self.t.add_duration(other) }
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_add_duration(other)? })
}

pub fn sub_duration(&self, other: &Duration) -> Instant {
Instant { t: self.t.sub_duration(other) }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant { t: self.t.checked_sub_duration(other)? })
}
}

Expand All @@ -327,16 +315,12 @@ mod inner {
self.t.sub_timespec(&other.t)
}

pub fn add_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.add_duration(other) }
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
self.t.checked_add_duration(other).map(|t| SystemTime { t })
Some(SystemTime { t: self.t.checked_add_duration(other)? })
}

pub fn sub_duration(&self, other: &Duration) -> SystemTime {
SystemTime { t: self.t.sub_duration(other) }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime { t: self.t.checked_sub_duration(other)? })
}
}

Expand Down
Loading