aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys
diff options
context:
space:
mode:
authorFenrir <[email protected]>2017-02-17 16:24:20 -0700
committerFenrir <[email protected]>2017-02-18 18:04:15 -0700
commit602f632e4a30e61163dd187de1a5ae171a323d4c (patch)
tree5ca7e8449c775a91c8e7192a54319641faebf2a7 /ctr-std/src/sys
parentYet another bugfix (diff)
downloadctru-rs-602f632e4a30e61163dd187de1a5ae171a323d4c.tar.xz
ctru-rs-602f632e4a30e61163dd187de1a5ae171a323d4c.zip
Overhaul Instant impl
Diffstat (limited to 'ctr-std/src/sys')
-rw-r--r--ctr-std/src/sys/unix/time.rs81
1 files changed, 42 insertions, 39 deletions
diff --git a/ctr-std/src/sys/unix/time.rs b/ctr-std/src/sys/unix/time.rs
index f4e24e4..052bd32 100644
--- a/ctr-std/src/sys/unix/time.rs
+++ b/ctr-std/src/sys/unix/time.rs
@@ -107,16 +107,18 @@ mod inner {
use fmt;
use libc;
use sys::cvt;
+ use sys_common::mul_div_u64;
use time::Duration;
+ use super::NSEC_PER_SEC;
use super::Timespec;
use spin;
use libctru;
- #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Instant {
- t: Timespec,
+ t: u64
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -135,27 +137,29 @@ mod inner {
impl Instant {
pub fn now() -> Instant {
- let usec = monotonic_usec();
-
- let s = libc::timeval {
- tv_sec: (usec / 1_000_000) as libc::time_t,
- tv_usec: (usec % 1_000_000) as libc::c_long,
- };
- return Instant::from(s)
+ Instant { t: ctr_absolute_time() }
}
pub fn sub_instant(&self, other: &Instant) -> Duration {
- self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
- panic!("other was less than the current instant")
- })
+ let info = info();
+ let diff = self.t.checked_sub(other.t)
+ .expect("second instant is later than self");
+ let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
+ Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
}
pub fn add_duration(&self, other: &Duration) -> Instant {
- Instant { t: self.t.add_duration(other) }
+ Instant {
+ t: self.t.checked_add(dur2intervals(other))
+ .expect("overflow when adding duration to instant"),
+ }
}
pub fn sub_duration(&self, other: &Duration) -> Instant {
- Instant { t: self.t.sub_duration(other) }
+ Instant {
+ t: self.t.checked_sub(dur2intervals(other))
+ .expect("overflow when adding duration to instant"),
+ }
}
}
@@ -163,16 +167,11 @@ mod inner {
static TICK: spin::Once<u64> = spin::Once::new();
// A source of monotonic time based on ticks of the 3DS CPU. Returns the
- // number of microseconds elapsed since an arbitrary time in the past
- //
- // Note that svcGetSystemTick always runs at 268MHz, even on a
- // New 3DS running in 804MHz mode
- //
- // See https://www.3dbrew.org/wiki/Hardware#Common_hardware
- fn monotonic_usec() -> u64 {
+ // number of system ticks elapsed since an arbitrary point in the past
+ fn ctr_absolute_time() -> u64 {
let first_tick = get_first_tick();
let current_tick = get_system_tick();
- (current_tick - first_tick) / 268
+ current_tick - first_tick
}
// The first time this function is called, it generates and returns the
@@ -185,32 +184,36 @@ mod inner {
}
// Gets the current system tick
+ #[inline]
fn get_system_tick() -> u64 {
unsafe { libctru::svc::svcGetSystemTick() }
}
- impl fmt::Debug for Instant {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Instant")
- .field("tv_sec", &self.t.t.tv_sec)
- .field("tv_nsec", &self.t.t.tv_nsec)
- .finish()
- }
+ // A struct representing the clock speed of the 3DS
+ struct CtrClockInfo {
+ numer: u32,
+ denom: u32,
}
- impl From<libc::timeval> for Instant {
- fn from(t: libc::timeval) -> Instant {
- Instant::from(libc::timespec {
- tv_sec: t.tv_sec,
- tv_nsec: (t.tv_usec * 1000) as libc::c_long,
- })
+ // Initializes the CtrClockInfo struct
+ //
+ // Note that svcGetSystemTick always runs at 268MHz (268,111,856Hz), even
+ // on a New 3DS running in 804MHz mode
+ //
+ // See https://www.3dbrew.org/wiki/Hardware#Common_hardware
+ fn info() -> CtrClockInfo {
+ CtrClockInfo {
+ numer: 1_000_000_000,
+ denom: 268_111_856,
}
}
- impl From<libc::timespec> for Instant {
- fn from(t: libc::timespec) -> Instant {
- Instant { t: Timespec { t: t } }
- }
+ fn dur2intervals(dur: &Duration) -> 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)
}
impl SystemTime {