Browse Source

Fix some accuracy / retval issues with monotonic

pull/10/head
Ian Chamberlain 3 years ago
parent
commit
7abc5e5366
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 25
      src/lib.rs

25
src/lib.rs

@ -1,9 +1,7 @@
#![no_std] #![no_std]
use core::any::Any; use core::convert::TryFrom;
use core::convert::{TryFrom, TryInto};
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use core::num::TryFromIntError;
use core::ptr; use core::ptr;
extern crate libc; extern crate libc;
@ -58,6 +56,7 @@ unsafe extern "C" fn clock_gettime(
tp: *mut libc::timespec, tp: *mut libc::timespec,
) -> libc::c_int { ) -> libc::c_int {
let mut retval = -1; let mut retval = -1;
match clock_id { match clock_id {
libc::CLOCK_REALTIME => { libc::CLOCK_REALTIME => {
let mut tv = MaybeUninit::uninit(); let mut tv = MaybeUninit::uninit();
@ -71,15 +70,19 @@ unsafe extern "C" fn clock_gettime(
} }
libc::CLOCK_MONOTONIC => { libc::CLOCK_MONOTONIC => {
if let Ok(tick) = i64::try_from(ctru_sys::svcGetSystemTick()) { if let Ok(tick) = i64::try_from(ctru_sys::svcGetSystemTick()) {
let sysclock = i64::from(ctru_sys::SYSCLOCK_ARM11); retval = 0;
(*tp).tv_sec = tick / sysclock;
let sysclock_rate = i64::from(ctru_sys::SYSCLOCK_ARM11);
// This cast to i32 is safe because the remainder will always be less than sysclock, (*tp).tv_sec = tick / sysclock_rate;
// which fits in an i32, and it's required to convert to f64.
let remainder = f64::from((tick - sysclock * (*tp).tv_sec) as i32); // this should always fit in an f64 easily, since it's < sysclock_rate
// Casting to int rounds towards zero, which seems fine in this case. let remainder = (tick % sysclock_rate) as f64;
(*tp).tv_nsec = (1000.0 * remainder / ctru_sys::CPU_TICKS_PER_USEC) as i32;
// 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 { } 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() = ECTRU
} }
} }

Loading…
Cancel
Save