diff options
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") |