aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys
diff options
context:
space:
mode:
authorFenrir <[email protected]>2017-02-03 19:11:41 -0700
committerFenrir <[email protected]>2017-02-18 18:04:15 -0700
commitdcf862c3dbb56d00bad54132db66bc7b301e5138 (patch)
treedc6c84139ce40d8438015da94268a01dfbbda74c /ctr-std/src/sys
parentctr-std: Add Time module (diff)
downloadctru-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.rs45
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")