Browse Source

Merge pull request #10 from ian-h-chamberlain/gettime/monotonic

Impl `clock_gettime` for `CLOCK_MONOTONIC`
pull/11/head
Meziu 3 years ago committed by GitHub
parent
commit
ac276169d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      src/lib.rs

24
src/lib.rs

@ -1,10 +1,15 @@ @@ -1,10 +1,15 @@
#![no_std]
use core::convert::TryFrom;
use core::mem::MaybeUninit;
use core::ptr;
extern crate libc;
// avoid conflicting a real POSIX errno by using a value < 0
// should we define this in ctru-sys somewhere or something?
const ECTRU: libc::c_int = -1;
/// Call this somewhere to force Rust to link this module.
/// The call doesn't need to execute, just exist.
///
@ -51,6 +56,7 @@ unsafe extern "C" fn clock_gettime( @@ -51,6 +56,7 @@ unsafe extern "C" fn clock_gettime(
tp: *mut libc::timespec,
) -> libc::c_int {
let mut retval = -1;
match clock_id {
libc::CLOCK_REALTIME => {
let mut tv = MaybeUninit::uninit();
@ -62,6 +68,24 @@ unsafe extern "C" fn clock_gettime( @@ -62,6 +68,24 @@ unsafe extern "C" fn clock_gettime(
(*tp).tv_sec = tv.tv_sec;
}
}
libc::CLOCK_MONOTONIC => {
if let Ok(tick) = i64::try_from(ctru_sys::svcGetSystemTick()) {
retval = 0;
let sysclock_rate = i64::from(ctru_sys::SYSCLOCK_ARM11);
(*tp).tv_sec = tick / sysclock_rate;
// this should always fit in an f64 easily, since it's < sysclock_rate
let remainder = (tick % sysclock_rate) as f64;
// cast to i32 rounds toward zero, which should be fine for this use case
(*tp).tv_nsec = (1000.0 * (remainder / ctru_sys::CPU_TICKS_PER_USEC)) as i32;
} else {
// Too many ticks, this device has been on for >1000 years!
// We would have otherwise given a negative result back to caller
*__errno() = ECTRU
}
}
_ => *__errno() = libc::EINVAL,
}

Loading…
Cancel
Save