diff options
| author | Fenrir <[email protected]> | 2017-02-03 19:11:41 -0700 |
|---|---|---|
| committer | Fenrir <[email protected]> | 2017-02-18 18:04:15 -0700 |
| commit | dcf862c3dbb56d00bad54132db66bc7b301e5138 (patch) | |
| tree | dc6c84139ce40d8438015da94268a01dfbbda74c /ctr-std/src/sys | |
| parent | ctr-std: Add Time module (diff) | |
| download | ctru-rs-dcf862c3dbb56d00bad54132db66bc7b301e5138.tar.xz ctru-rs-dcf862c3dbb56d00bad54132db66bc7b301e5138.zip | |
use svcGetSystemTick for Instant
Diffstat (limited to 'ctr-std/src/sys')
| -rw-r--r-- | ctr-std/src/sys/unix/time.rs | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/ctr-std/src/sys/unix/time.rs b/ctr-std/src/sys/unix/time.rs index 3eea581..9c80560 100644 --- a/ctr-std/src/sys/unix/time.rs +++ b/ctr-std/src/sys/unix/time.rs @@ -111,6 +111,9 @@ mod inner { use super::Timespec; + use spin; + use libctru; + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Instant { t: Timespec, @@ -131,18 +134,13 @@ mod inner { }; impl Instant { - // devkitARM does not expose monotonic time functions or types, - // so we fall back to constructing Instant with gettimeofday(2) pub fn now() -> Instant { - use ptr; + let ms = monotonic_ms(); - let mut s = libc::timeval { - tv_sec: 0, - tv_usec: 0, + let s = libc::timeval { + tv_sec: ms as i32 * 1_000_000, + tv_usec: ms as i32, }; - cvt(unsafe { - libc::gettimeofday(&mut s, ptr::null_mut()) - }).unwrap(); return Instant::from(s) } @@ -161,6 +159,35 @@ mod inner { } } + // The initial system tick after which all Instants occur + static TICK: spin::Once<u64> = spin::Once::new(); + + // Returns a monotonic timer in microseconds + // + // 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_ms() -> u64 { + let first_tick = get_first_tick(); + let current_tick = get_system_tick(); + (current_tick - first_tick / 268) + } + + // The first time this function is called, it generates and returns the + // initial system tick used to create Instants + // + // subsequent calls to this function return the previously generated + // tick value + fn get_first_tick() -> u64 { + *TICK.call_once(get_system_tick) + } + + // Gets the current system tick + 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") |