Skip to content

Commit fd49cf7

Browse files
Andrew Boiecarlescufi
Andrew Boie
authored andcommitted
kernel: timeout: add syscall for runtime clk freq
If the system sets its clock frequency at runtime, this is stored in a variable that can't be directly read by user mode. For this case only, add a system call to fetch its value and modify the definition of sys_clock_hw_cycles_per_sec() to use it. Since this is now a system call, store in a temporary variable inside z_ms_to_ticks(). The syscall overhead only applies when called from user mode, other contexts are completely inlined. Added stub syscall header for mocking framework, to get rid of inclusion errors. Fixes: #16238 Signed-off-by: Andrew Boie <[email protected]>
1 parent e541b16 commit fd49cf7

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

include/sys_clock.h

+17-6
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,21 @@ extern int _sys_clock_always_on;
3131
extern void z_enable_sys_clock(void);
3232
#endif
3333

34-
static inline int sys_clock_hw_cycles_per_sec(void)
35-
{
3634
#if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME)
35+
__syscall int z_clock_hw_cycles_per_sec_runtime_get(void);
36+
37+
static inline int z_impl_z_clock_hw_cycles_per_sec_runtime_get(void)
38+
{
3739
extern int z_clock_hw_cycles_per_sec;
3840

3941
return z_clock_hw_cycles_per_sec;
42+
}
43+
#endif /* CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME */
44+
45+
static inline int sys_clock_hw_cycles_per_sec(void)
46+
{
47+
#if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME)
48+
return z_clock_hw_cycles_per_sec_runtime_get();
4049
#else
4150
return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
4251
#endif
@@ -100,11 +109,11 @@ static ALWAYS_INLINE s32_t z_ms_to_ticks(s32_t ms)
100109
#ifdef CONFIG_SYS_CLOCK_EXISTS
101110

102111
#ifdef _NEED_PRECISE_TICK_MS_CONVERSION
112+
int cyc = sys_clock_hw_cycles_per_sec();
113+
103114
/* use 64-bit math to keep precision */
104-
return (s32_t)ceiling_fraction(
105-
(s64_t)ms * sys_clock_hw_cycles_per_sec(),
106-
((s64_t)MSEC_PER_SEC * sys_clock_hw_cycles_per_sec()) /
107-
CONFIG_SYS_CLOCK_TICKS_PER_SEC);
115+
return (s32_t)ceiling_fraction((s64_t)ms * cyc,
116+
((s64_t)MSEC_PER_SEC * cyc) / CONFIG_SYS_CLOCK_TICKS_PER_SEC);
108117
#else
109118
/* simple division keeps precision */
110119
s32_t ms_per_tick = MSEC_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
@@ -234,4 +243,6 @@ struct _timeout {
234243
}
235244
#endif
236245

246+
#include <syscalls/sys_clock.h>
247+
237248
#endif /* ZEPHYR_INCLUDE_SYS_CLOCK_H_ */

kernel/timeout.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ static int announce_remaining;
2828

2929
#if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME)
3030
int z_clock_hw_cycles_per_sec = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
31-
#endif
31+
32+
#ifdef CONFIG_USERSPACE
33+
Z_SYSCALL_HANDLER(z_clock_hw_cycles_per_sec_runtime_get)
34+
{
35+
return z_impl_z_clock_hw_cycles_per_sec_runtime_get();
36+
}
37+
#endif /* CONFIG_USERSPACE */
38+
#endif /* CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME */
3239

3340
static struct _timeout *first(void)
3441
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/

0 commit comments

Comments
 (0)