From 1ce91d55c984746243da329e34b5279bfe5c4f38 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Wed, 28 Aug 2019 13:19:26 +0000 Subject: [PATCH] kernel: reimplement k_uptime_get_32() The current implementation does not return the low 32 bits of k_uptime_get() as suggested by it's documentation; it returns the number of milliseconds represented by the low 32-bits of the underlying system clock. The truncation before translation results in discontinuities at every point where the system clock increments bit 33. Reimplement it using the full-precision value, and update the documentation to note that this variant has little value for long-running applications. Closes #18739. Signed-off-by: Peter Bigot --- include/kernel.h | 20 ++++++++++++-------- kernel/timeout.c | 12 ------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 41ce40beb1bd0..96497fd957679 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1676,22 +1676,26 @@ void k_disable_sys_clock_always_on(void); /** * @brief Get system uptime (32-bit version). * - * This routine returns the lower 32-bits of the elapsed time since the system - * booted, in milliseconds. + * This routine returns the lower 32 bits of the system uptime in + * milliseconds. * - * This routine can be more efficient than k_uptime_get(), as it reduces the - * need for interrupt locking and 64-bit math. However, the 32-bit result - * cannot hold a system uptime time larger than approximately 50 days, so the - * caller must handle possible rollovers. + * Because correct conversion requires full precision of the system + * clock there is no benefit to using this over k_uptime_get() unless + * you know the application will never run long enough for the system + * clock to approach 2^32 ticks. Calls to this function may involve + * interrupt blocking and 64-bit math. * * @note While this function returns time in milliseconds, it does not mean it * has millisecond resolution. The actual resolution depends on * :option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` config option, and with the default * setting of 100, system time is updated in increments of 10ms. * - * @return Current uptime in milliseconds. + * @return The low 32 bits of the current uptime, in milliseconds. */ -__syscall u32_t k_uptime_get_32(void); +static inline u32_t k_uptime_get_32(void) +{ + return (u32_t)k_uptime_get(); +} /** * @brief Get elapsed time. diff --git a/kernel/timeout.c b/kernel/timeout.c index a24f0b4b6e4da..9e9d000e01614 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -234,18 +234,6 @@ u32_t z_tick_get_32(void) #endif } -u32_t z_impl_k_uptime_get_32(void) -{ - return __ticks_to_ms(z_tick_get_32()); -} - -#ifdef CONFIG_USERSPACE -Z_SYSCALL_HANDLER(k_uptime_get_32) -{ - return z_impl_k_uptime_get_32(); -} -#endif - s64_t z_impl_k_uptime_get(void) { return __ticks_to_ms(z_tick_get());