Thread's CPU time
giulio at bela.io
Mon May 2 11:42:12 CEST 2022
Philippe Gerum wrote on 29/04/2022 17:29:>
> Giulio Moro via Xenomai <xenomai at xenomai.org> writes:
>> Hi everyone,
>> From /proc/xenomai/sched/stat I infer there must be an internal struct
>> somewhere keeping track of how much CPU time is actually used by each
>> thread. Is there any way to access this kind of statistics from a
>> running Xenomai user space program without leaving primary mode and
>> without attempting to read this file? I am implementing an
>> infrastructure to measure the CPU time of a given block of
>> code. Currently I am using Cobalt's clock_gettime(), but this only
>> works reliably if the task does not get preempted or otherwise
>> rescheduled between the two calls.
>> I have run this kind of tests offline before and that's all nice and good, but I am looking for a lightweight and non invasive way of benchmarking particular sections of large-ish programs with minimal modifications.
> For xenomai3, you may want to have a look at cobalt_thread_stat() from
> the internal API (sys/cobalt.h). The field of interest returned in
> struct cobalt_threadstat would be 'xtime' (nsecs).
Thanks, I tried to implement something based on that and it seems to carry a considerable overhead over calling Cobalt's clock_gettime(): about a 3% CPU increase (as measured by /proc/xenomai/sched/stat) for 6 calls to `cobalt_thread_stat()` during a periodic task with period 360us, which is suboptimal.
A look at COBALT_SYSCALL(thread_getstat, ...) suggests that it would be possible to get just xtime for significantly cheaper than a full clock_gettime() call, considering not only that there would be less memory to be copied around, but also that - afaict - the irqsave / irqrestore calls wouldn't be needed. I am wondering whether, to this effect, it would make sense to implement `CLOCK_THREAD_CPUTIME_ID` for Cobalt's clock_gettime(), returning the 'xtime' field of this struct, e.g. (untested and probably missing includes):
diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index 16cc8b20a..434380509 100644
@@ -134,6 +134,14 @@ int __cobalt_clock_gettime(clockid_t clock_id, struct timespec64 *ts)
if (pipeline_get_host_time(ts) != 0)
+ case CLOCK_THREAD_CPUTIME_ID:
+ struct xnthread *thread = xnthread_current();
+ if (thread == NULL)
+ return -EPERM;
+ ns2ts(ts, xnstat_exectime_get_total(&thread->stat.account));
ret = do_ext_clock(clock_id, read_monotonic, ns);
Or am I oversimplifying here?
More information about the Xenomai