Skip to content

Commit 85e2ef8

Browse files
committed
posix: Add posix CLOCK_THREAD_CPUTIME_ID support
Add posix 'CLOCK_THREAD_CPUTIME_ID' support to measure the total CPU execution time of the current thread. Signed-off-by: James Roy <rruuaanng@outlook.com>
1 parent b15404f commit 85e2ef8

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

lib/posix/options/Kconfig.timer

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ if POSIX_TIMERS
1717

1818
config POSIX_THREAD_CPUTIME
1919
bool "POSIX per-thread CPU-time clocks"
20+
select THREAD_RUNTIME_STATS
21+
select SCHED_THREAD_USAGE_ANALYSIS
2022
help
2123
This enables CLOCK_THREAD_CPUTIME_ID.
2224

lib/posix/options/clock.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,59 @@ int clock_gettime(clockid_t clock_id, struct timespec *ts)
2727
return 0;
2828
}
2929

30+
#ifdef CONFIG_USERSPACE
31+
int z_vrfy___posix_clock_get_base(clockid_t clock_id, struct timespec *ts)
32+
{
33+
K_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts)));
34+
return z_impl___posix_clock_get_base(clock_id, ts);
35+
}
36+
#include <zephyr/syscalls/__posix_clock_get_base_mrsh.c>
37+
#endif
38+
39+
int clock_gettime(clockid_t clock_id, struct timespec *ts)
40+
{
41+
struct timespec base;
42+
43+
switch (clock_id) {
44+
case CLOCK_MONOTONIC:
45+
base.tv_sec = 0;
46+
base.tv_nsec = 0;
47+
break;
48+
49+
case CLOCK_REALTIME:
50+
(void)__posix_clock_get_base(clock_id, &base);
51+
break;
52+
53+
#ifdef CONFIG_POSIX_THREAD_CPUTIME
54+
case CLOCK_THREAD_CPUTIME_ID:
55+
(void)__posix_clock_get_base(clock_id, &base);
56+
*ts = base;
57+
return 0;
58+
#endif /* CONFIG_POSIX_THREAD_CPUTIME */
59+
60+
default:
61+
errno = EINVAL;
62+
return -1;
63+
}
64+
65+
uint64_t ticks = k_uptime_ticks();
66+
uint64_t elapsed_secs = ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
67+
uint64_t nremainder = ticks - elapsed_secs * CONFIG_SYS_CLOCK_TICKS_PER_SEC;
68+
69+
ts->tv_sec = (time_t) elapsed_secs;
70+
/* For ns 32 bit conversion can be used since its smaller than 1sec. */
71+
ts->tv_nsec = (int32_t) k_ticks_to_ns_floor32(nremainder);
72+
73+
ts->tv_sec += base.tv_sec;
74+
ts->tv_nsec += base.tv_nsec;
75+
if (ts->tv_nsec >= NSEC_PER_SEC) {
76+
ts->tv_sec++;
77+
ts->tv_nsec -= NSEC_PER_SEC;
78+
}
79+
80+
return 0;
81+
}
82+
3083
int clock_getres(clockid_t clock_id, struct timespec *res)
3184
{
3285
BUILD_ASSERT(CONFIG_SYS_CLOCK_TICKS_PER_SEC > 0 &&

0 commit comments

Comments
 (0)