tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59127: clock_getres(2) returns EINVAL for CLOCK_{PROCESS,THREAD}_CPUTIME_ID
Hi,
I just filed a PR with the attached patch to make clock_getres(2)
support these two clocks. I will commit the patch in a week or two if no
one objects:
https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=59127
The reason why this matters to me is that lang/ghc910 has been silently
broken. Its function System.CPUTime.cpuTimePrecision tries to call
clock_getres(CLOCK_PROCESS_CPUTIME_ID) if:
#elif _POSIX_TIMERS > 0 && defined(_POSIX_CPUTIME) && _POSIX_CPUTIME >= 0
which holds true on NetBSD, but then the syscall returns EINVAL:
% ghci
GHCi, version 9.10.1: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/pho/.ghci
ghci> :m System.CPUTime
ghci> cpuTimePrecision
*** Exception: clock_getres: invalid argument (Invalid argument)
GHC still needs to be patched in the meantime but I believe the kernel
should support this.From ebf335048a3a4684b05c4efd07acaeae2b8c0cf0 Mon Sep 17 00:00:00 2001
From: PHO <pho%cielonegro.org@localhost>
Date: Tue, 4 Mar 2025 21:28:46 +0900
Subject: [PATCH] clock_getres(2): Support CLOCK_{PROCESS,THREAD}_CPUTIME_ID
The syscall previously returned EINVAL for these two clocks. It still has
no support for CLOCK_VIRTUAL and CLOCK_PROF but clock_gettime(2) doesn't
either.
---
sys/kern/kern_time.c | 2 ++
tests/lib/libc/sys/t_clock_gettime.c | 34 ++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 91d259d810ac5..213a151b6b506 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -339,6 +339,8 @@ clock_getres1(clockid_t clock_id, struct timespec *ts)
switch (clock_id) {
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
ts->tv_sec = 0;
if (tc_getfrequency() > 1000000000)
ts->tv_nsec = 1;
diff --git a/tests/lib/libc/sys/t_clock_gettime.c b/tests/lib/libc/sys/t_clock_gettime.c
index 6421b1ab0cb8c..7e0954c1244aa 100644
--- a/tests/lib/libc/sys/t_clock_gettime.c
+++ b/tests/lib/libc/sys/t_clock_gettime.c
@@ -285,12 +285,46 @@ ATF_TC_BODY(clock_gettime_thread_cputime_is_monotonic, tc)
CLOCK_THREAD_CPUTIME_ID, &waste_user_time);
}
+static void
+check_resolution(const char *clockname, clockid_t clockid)
+{
+ struct timespec ts;
+ int rv;
+
+ RLF(rv = clock_getres(clockid, &ts), "%s", clockname);
+ if (rv != -1) {
+ ATF_CHECK_MSG(ts.tv_sec == 0,
+ "The resolution of the clock %s is reported as %jd.%09jd which is"
+ " lower than a second; most likely an wrong value",
+ clockname, ts.tv_sec, ts.tv_nsec);
+ }
+}
+
+ATF_TC(clock_getres);
+ATF_TC_HEAD(clock_getres, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that clock_getres(2) returns some reasonable resolution for all supported clocks");
+}
+ATF_TC_BODY(clock_getres, tc)
+{
+ check_resolution("CLOCK_REALTIME", CLOCK_REALTIME);
+ check_resolution("CLOCK_MONOTONIC", CLOCK_MONOTONIC);
+ atf_tc_expect_fail("These clocks aren't supported but are documented in clock_gettime(2) for some reason");
+ check_resolution("CLOCK_VIRTUAL", CLOCK_VIRTUAL);
+ check_resolution("CLOCK_PROF", CLOCK_PROF);
+ atf_tc_expect_pass();
+ check_resolution("CLOCK_PROCESS_CPUTIME_ID", CLOCK_PROCESS_CPUTIME_ID);
+ check_resolution("CLOCK_THREAD_CPUTIME_ID", CLOCK_THREAD_CPUTIME_ID);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, clock_gettime_real);
ATF_TP_ADD_TC(tp, clock_gettime_process_cputime_is_monotonic);
ATF_TP_ADD_TC(tp, clock_gettime_thread_cputime_is_monotonic);
+ ATF_TP_ADD_TC(tp, clock_getres);
return atf_no_error();
}
Home |
Main Index |
Thread Index |
Old Index