relibc: make CLOCK_MONOTONIC_RAW a distinct id on Redox

CLOCK_MONOTONIC_RAW previously equalled CLOCK_MONOTONIC (both 4), which is
semantically true on Redox (the monotonic clock is already un-slewed) but
breaks portable code that switch()es on both — e.g. Mesa's intel_gem.c had two
case labels with the same value (compile error). Give it a distinct id (5) and
map it back to the monotonic clock (id 4) in clock_gettime()/clock_getres()
before hitting the kernel time scheme, restoring Linux-compatible semantics for
all consumers.

cargo check clean for x86_64-unknown-redox.
This commit is contained in:
2026-08-01 13:32:31 +03:00
parent 599627a926
commit 8535f7b843
2 changed files with 19 additions and 4 deletions
+6 -2
View File
@@ -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;
+13 -2
View File
@@ -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<Out<timespec>>) -> 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<timespec>) -> 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/<id> 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(())
}