Implement timespec_get and timespec_getres

`timespec_get` and `timespec_getres` are both C23 functions. They're
similar to the POSIX functions `clock_gettime` and `clock_getres`, but
both sets of functions define extra, exclusive features. I didn't
implement the extra features yet, partially because Redox doesn't seem
to support them yet either.
This commit is contained in:
Josh Megnauth
2025-12-04 15:00:48 -05:00
parent 14b011da84
commit 4538fdb0c9
3 changed files with 57 additions and 6 deletions
+9
View File
@@ -22,3 +22,12 @@ pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2;
pub const CLOCKS_PER_SEC: c_long = 1_000_000;
pub const TIMER_ABSTIME: c_int = 1;
// Constants for timespec_get and timespec_getres which are C23 analogues to
// clock_gettime/getres.
// The values are offset by one for simplicity since zero represents an error.
/// `TIME_UTC` returns the time since the Unix epoch.
pub const TIME_UTC: c_int = sys::CLOCK_REALTIME + 1;
/// `TIME_MONOTONIC` returns the time from the monotonically increasing clock.
pub const TIME_MONOTONIC: c_int = sys::CLOCK_MONOTONIC + 1;
+20 -3
View File
@@ -599,10 +599,27 @@ pub unsafe extern "C" fn timer_settime(
.or_minus_one_errno()
}
/// ISO C equivalent to [`Sys::clock_gettime`].
///
/// The main differences are that this function:
/// * returns `0` on error and `base` on success
/// * only mandates TIME_UTC as a base
///
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/timespec_get.html>.
// #[unsafe(no_mangle)]
pub extern "C" fn timespec_get(ts: *mut timespec, base: c_int) -> c_int {
unimplemented!();
#[unsafe(no_mangle)]
pub extern "C" fn timespec_get(tp: *mut timespec, base: c_int) -> c_int {
let tp = unsafe { Out::nonnull(tp) };
Sys::clock_gettime(base - 1, tp).map(|()| base).unwrap_or(0)
}
/// ISO C equivalent to [`Sys::clock_getres`].
///
/// The main differences are that this function:
/// * returns `0` on error and `base` on success
/// * only mandates TIME_UTC as a base
pub extern "C" fn timespec_getres(res: *mut timespec, base: c_int) -> c_int {
let res = unsafe { Out::nullable(res) };
Sys::clock_getres(base - 1, res).map(|()| base).unwrap_or(0)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tzset.html>.
+28 -3
View File
@@ -1,19 +1,44 @@
#include <time.h>
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <time.h>
#include "test_helpers.h"
int main(void) {
struct timespec tm = {0, 0};
struct timespec tm = {0};
int cgt = clock_gettime(CLOCK_REALTIME, &tm);
ERROR_IF(clock_gettime, cgt, == -1);
cgt = clock_getres(CLOCK_REALTIME, &tm);
ERROR_IF(clock_getres, cgt, == -1);
cgt = timespec_get(&tm, TIME_UTC);
if (cgt != TIME_UTC) {
errx(
EXIT_FAILURE,
"timespec_get should have returned %d but returned %d\n",
TIME_UTC,
cgt
);
}
cgt = timespec_getres(&tm, TIME_UTC);
if (cgt != TIME_UTC) {
errx(
EXIT_FAILURE,
"timespec_getres should have returned %d but returned %d\n",
TIME_UTC,
cgt
);
}
time_t t = time(NULL);
ERROR_IF(time, t, == (time_t)-1);
// TODO: Support clock() on Redox
// clock_t c = clock();
// ERROR_IF(clock, c, == (clock_t)-1);
return EXIT_SUCCESS;
}