Browse Source

use svcGetSystemTick for Instant

pull/10/head
Fenrir 8 years ago
parent
commit
dcf862c3db
  1. 3
      ctr-std/Cargo.toml
  2. 1
      ctr-std/src/lib.rs
  3. 45
      ctr-std/src/sys/unix/time.rs

3
ctr-std/Cargo.toml

@ -9,6 +9,9 @@ git = "https://github.com/rust-lang-nursery/compiler-builtins"
[dependencies.ctr-libc] [dependencies.ctr-libc]
path = "../ctr-libc" path = "../ctr-libc"
[dependencies.ctru-sys]
path = "../ctru-sys"
[dependencies.alloc_system] [dependencies.alloc_system]
version = "0.1.1" version = "0.1.1"

1
ctr-std/src/lib.rs

@ -52,6 +52,7 @@ extern crate compiler_builtins;
// 3ds-specific dependencies // 3ds-specific dependencies
extern crate ctr_libc as libc; extern crate ctr_libc as libc;
extern crate ctru_sys as libctru;
// stealing spin's mutex implementation for now // stealing spin's mutex implementation for now
extern crate spin; extern crate spin;

45
ctr-std/src/sys/unix/time.rs

@ -111,6 +111,9 @@ mod inner {
use super::Timespec; use super::Timespec;
use spin;
use libctru;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Instant { pub struct Instant {
t: Timespec, t: Timespec,
@ -131,18 +134,13 @@ mod inner {
}; };
impl Instant { 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 { pub fn now() -> Instant {
use ptr; let ms = monotonic_ms();
let mut s = libc::timeval { let s = libc::timeval {
tv_sec: 0, tv_sec: ms as i32 * 1_000_000,
tv_usec: 0, tv_usec: ms as i32,
}; };
cvt(unsafe {
libc::gettimeofday(&mut s, ptr::null_mut())
}).unwrap();
return Instant::from(s) 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 { impl fmt::Debug for Instant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Instant") f.debug_struct("Instant")

Loading…
Cancel
Save