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:
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user