Philippe Gerum wrote on 29/04/2022 17:29:>
Giulio Moro via Xenomai <[email protected]> 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.

Thanks,
Giulio

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
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -134,6 +134,14 @@ int __cobalt_clock_gettime(clockid_t clock_id, struct 
timespec64 *ts)
                if (pipeline_get_host_time(ts) != 0)
                        return -EINVAL;
                break;
+       case CLOCK_THREAD_CPUTIME_ID:
+               {
+                       struct xnthread *thread = xnthread_current();
+                       if (thread == NULL)
+                               return -EPERM;
+                       ns2ts(ts, 
xnstat_exectime_get_total(&thread->stat.account));
+               }
+               break;
        default:
                ret = do_ext_clock(clock_id, read_monotonic, ns);
                if (ret)
```

Or am I oversimplifying here?

Reply via email to