diff --git a/src/header/time/redox.rs b/src/header/time/redox.rs index 0291f9e004..4a17c0fed9 100644 --- a/src/header/time/redox.rs +++ b/src/header/time/redox.rs @@ -2,5 +2,9 @@ use crate::platform::types::c_int; pub const CLOCK_REALTIME: c_int = 1; pub const CLOCK_MONOTONIC: c_int = 4; -// Redox's monotonic clock is the un-slewed hardware timer, so RAW is identical. -pub const CLOCK_MONOTONIC_RAW: c_int = 4; +// Redox's monotonic clock is already the un-slewed hardware timer, so RAW reads +// the same underlying source. It MUST use a distinct id from CLOCK_MONOTONIC, +// though, because portable code (e.g. Mesa's intel_gem) `switch`es on both and +// two equal case values won't compile. clock_gettime()/clock_getres() map this +// id back onto the monotonic clock (id 4) before hitting the kernel time scheme. +pub const CLOCK_MONOTONIC_RAW: c_int = 5; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index b10573e937..fa4d461efc 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -55,7 +55,8 @@ use crate::{ sys_time::timezone, sys_utsname::{UTSLENGTH, utsname}, time::{ - CLOCK_MONOTONIC, CLOCK_REALTIME, TIMER_ABSTIME, itimerspec, timer_internal_t, timespec, + CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_REALTIME, TIMER_ABSTIME, itimerspec, + timer_internal_t, timespec, }, unistd::{F_OK, R_OK, SEEK_CUR, SEEK_END, SEEK_SET, W_OK, X_OK}, }, @@ -307,7 +308,8 @@ unsafe { BRK_CUR = addr }; fn clock_getres(clk_id: clockid_t, res: Option>) -> Result<()> { let path = match clk_id { CLOCK_REALTIME => "/scheme/time/1/getres", - CLOCK_MONOTONIC => "/scheme/time/4/getres", + // CLOCK_MONOTONIC_RAW shares the monotonic clock source on Redox. + CLOCK_MONOTONIC | CLOCK_MONOTONIC_RAW => "/scheme/time/4/getres", _ => return Err(Errno(EINVAL)), }; let timerfd = FdGuard::open(path, syscall::O_RDONLY)?; @@ -334,6 +336,15 @@ unsafe { } fn clock_gettime(clk_id: clockid_t, tp: Out) -> Result<()> { + // CLOCK_MONOTONIC_RAW is a distinct clock id (so portable switch()es + // compile) but reads the same un-slewed monotonic source; libredox uses + // the id directly as the /scheme/time/ number, which only has 1 and + // 4, so translate RAW back to CLOCK_MONOTONIC here. + let clk_id = if clk_id == CLOCK_MONOTONIC_RAW { + CLOCK_MONOTONIC + } else { + clk_id + }; libredox::clock_gettime(clk_id as usize, tp)?; Ok(()) }