tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: nonexistent clocks
Hi,
I am moving this to tech-kern as it's getting technical
and I include a diff; please let me know if this is not
the approproate list (I am pretty new to netbsd).
The clock_gettime(2) manpage documents CLOCK_VIRTUAL and CLOCK_PROF,
but the clock_*() functions fail (EINVAL) on these clocks.
In fact, a test in tests/ (see below) expect them to fail.
I think it is confusing to list these clocks in ths manpage
among other valid clocks, if they are not a valid argument
to the clock functions; and I believe the manpage
would be better off without them.
Looking at sys/kern/kern_time.c, these clocks indeed cannot be read
or set; but perhaps (I am speculating here) they still do exist -
as the underlying clocks for the respective itimers, namely ITIMER_VIRTUAL
and ITIMER_PROF. If that is the case, the manpage should either clearly
state that these clocks cannot be read or set, or (imho preferably)
just not mention them at all.
Can someone who actually knows how this works shed some light please?
The diff and my naive clock and timer tests are below.
Jan
On Jun 25 13:17:00, hans%stare.cz@localhost wrote:
> Hi,
>
> > According to tests/lib/libc/sys/t_clock_gettime.c
> > ""These clocks aren't supported but are documented"
> > " in clock_gettime(2) for some reason"
>
> thanks for the pointer. I am new to NetBSD
> and am only getting into tests(7) so please bare with me.
>
> According to these test results (random google hit, but a recent run)
>
> https://www.netbsd.org/~martin/landisk-atf/last_atf.html#lib_libc_sys_t_clock_gettime_clock_getres
>
> calling clock_getres() on these two clocks is expected to fail.
> It seems a bit silly to test that NetBSD does _not_ support a clock.
> (Isn't clock_gettime() also expected to fail, if they do not exist? :-)
> Wouldn't it make more sense to just remove these from the documentation?
>
> > There's also a PR in about CLOCK_MONOTONIC & what it actually represents:
> > https://gnats.netbsd.org/60315
>
> Thank you. I am in fact studying the clock_*() interface on various
> unixes and what clocks they provide - see my naive take below.
>
> I guess my first question (please excuse the naivety) is where is
> NetBSD's clock_get*() implemented? That must be these, right?
>
> /usr/src/sys/kern/kern_time.c:clock_getres1()
> /usr/src/sys/kern/subr_time.c:clock_gettime1()
>
> These only support
>
> CLOCK_REALTIME
> CLOCK_MONOTONIC
> CLOCK_PROCESS_CPUTIME_ID
> CLOCK_THREAD_CPUTIME_ID
>
> and set EINVAL otherwise.
Index: lib/libc/sys/clock_settime.2
===================================================================
RCS file: /pub/NetBSD-CVS/src/lib/libc/sys/clock_settime.2,v
retrieving revision 1.27
diff -u -p -r1.27 clock_settime.2
--- lib/libc/sys/clock_settime.2 27 Sep 2016 11:11:43 -0000 1.27
+++ lib/libc/sys/clock_settime.2 25 Jun 2026 13:40:54 -0000
@@ -101,12 +101,6 @@ fail with an
error if it's the clock specified in a call to
.Fn clock_settime .
The origin of the clock is unspecified.
-.It Dv CLOCK_VIRTUAL
-identifies a clock that increments only when the CPU is running in
-user mode on behalf of the calling process.
-.It Dv CLOCK_PROF
-identifies a clock that increments when the CPU is running in user
-or kernel mode on behalf of the calling process.
.It Dv CLOCK_PROCESS_CPUTIME_ID
identifies a per process clock based on tick values.
This clock is not settable.
$ cat clock.c
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <err.h>
void
show(clockid_t id, char* name)
{
struct timespec ts;
struct timespec cr;
if (clock_gettime(id, &ts) == -1)
err(1, NULL);
if (clock_getres(id, &cr) == -1)
err(1, NULL);
printf("%s %10lld.%09ld s, %8ld ns resolution\n",
name, ts.tv_sec, ts.tv_nsec, cr.tv_nsec);
}
int
main(void)
{
#ifdef __APPLE__
show(CLOCK_REALTIME, "real time");
show(CLOCK_MONOTONIC, "monotonic");
show(CLOCK_UPTIME_RAW, "up time ");
show(CLOCK_PROCESS_CPUTIME_ID, "proc time");
#elif __OpenBSD__
show(CLOCK_REALTIME, "real time");
show(CLOCK_MONOTONIC, "monotonic");
show(CLOCK_BOOTTIME, "boot time");
show(CLOCK_UPTIME, "up time ");
show(CLOCK_PROCESS_CPUTIME_ID, "proc time");
#elif __FreeBSD__
show(CLOCK_REALTIME, "real time");
show(CLOCK_MONOTONIC, "monotonic");
show(CLOCK_BOOTTIME, "boot time");
show(CLOCK_UPTIME, "up time ");
show(CLOCK_PROCESS_CPUTIME_ID, "proc time");
show(CLOCK_VIRTUAL, "virt time");
show(CLOCK_PROF, "prof time");
#elif __NetBSD__
show(CLOCK_REALTIME, "real time");
show(CLOCK_MONOTONIC, "monotonic");
show(CLOCK_PROCESS_CPUTIME_ID, "proc time");
#else
show(CLOCK_REALTIME, "real time");
show(CLOCK_MONOTONIC, "monotonic");
show(CLOCK_BOOTTIME, "boot time");
show(CLOCK_PROCESS_CPUTIME_ID, "proc time");
#endif
return 0;
}
$ cat timer.c
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <err.h>
void
get(int which)
{
struct itimerval timer;
if (getitimer(which, &timer) == -1)
err(1, NULL);
printf("timer %d: %lld.%03ld remains, resets to %lld.%03ld\n",
which, (long long)timer.it_value.tv_sec, (long)timer.it_value.tv_usec,
(long long)timer.it_interval.tv_sec, (long) timer.it_interval.tv_usec);
}
void
set(int which, time_t sec, long usec)
{
struct itimerval timer = { { sec, usec}, { 1, 0 } };
if (setitimer(which, &timer, NULL) == -1)
err(1, NULL);
}
int
main(void)
{
unsigned s = 0;
struct timespec len = { 3, 0 };
struct timespec rem;
set(ITIMER_REAL, 1, 000);
set(ITIMER_VIRTUAL, 1, 500);
set(ITIMER_PROF, 2, 000);
#ifdef __NetBSD__
set(ITIMER_MONOTONIC, 2, 500);
#endif
get(ITIMER_REAL);
get(ITIMER_VIRTUAL);
get(ITIMER_PROF);
#ifdef __NetBSD__
get(ITIMER_MONOTONIC);
#endif
if ((s = sleep(2)) != 0) {
/* This will be EINTR'd by a SIGALRM from ITIMER_REAL */
printf("sleep interrupted: %u seconds remaining", s);
}
if (nanosleep(&len, &rem) == -1)
printf("sleep interrupted: %lld.%9ld remaining",
(long long) rem.tv_sec, (long) rem.tv_nsec);
return 0;
}
Home |
Main Index |
Thread Index |
Old Index