From 5cd6f424efa0f54342030bfceeeb8fc9ded99152 Mon Sep 17 00:00:00 2001 From: Andrey Dodonov Date: Tue, 22 Nov 2022 11:41:41 +0100 Subject: [PATCH 1/3] Fix overflow when converting to nanoseconds Part of the changes from https://github.com/zephyrproject-rtos/zephyr/pull/41602 --- include/sys/time_units.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/sys/time_units.h b/include/sys/time_units.h index f719230ed291..f3cfdf8afe82 100644 --- a/include/sys/time_units.h +++ b/include/sys/time_units.h @@ -129,8 +129,9 @@ static TIME_CONSTEXPR ALWAYS_INLINE uint64_t z_tmcvt(uint64_t t, uint32_t from_h } else { if (result32) { return (uint32_t)((t * to_hz + off) / from_hz); - } else { - return (t * to_hz + off) / from_hz; + } + else { + return (t / from_hz) * to_hz + ((t % from_hz) * to_hz + off) / from_hz; } } } From df2f1217245e7234c9c5517ca12311b01e95a441 Mon Sep 17 00:00:00 2001 From: Andrey Dodonov Date: Tue, 22 Nov 2022 11:42:52 +0100 Subject: [PATCH 2/3] Use microseconds instead of nanoseconds Cherry-picked from https://github.com/zephyrproject-rtos/zephyr/pull/41814 --- lib/posix/clock.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/posix/clock.c b/lib/posix/clock.c index c36f2401cc4c..547420242ba0 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -27,7 +27,6 @@ static struct k_spinlock rt_clock_base_lock; */ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) { - uint64_t elapsed_nsecs; struct timespec base; k_spinlock_key_t key; @@ -48,9 +47,14 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) return -1; } - elapsed_nsecs = k_ticks_to_ns_floor64(k_uptime_ticks()); - ts->tv_sec = (int32_t) (elapsed_nsecs / NSEC_PER_SEC); - ts->tv_nsec = (int32_t) (elapsed_nsecs % NSEC_PER_SEC); + uint64_t ticks = k_uptime_ticks(); + uint64_t elapsed_secs = k_ticks_to_ms_floor64(ticks) / MSEC_PER_SEC; + uint64_t nremainder = ticks - k_ms_to_ticks_floor64(MSEC_PER_SEC * elapsed_secs); + + ts->tv_sec = (time_t) elapsed_secs; + /* For ns 32 bit conversion can be used since its smaller than 1sec. */ + ts->tv_nsec = (int32_t) k_ticks_to_ns_floor32(nremainder); + ts->tv_sec += base.tv_sec; ts->tv_nsec += base.tv_nsec; From 798caa25037853beb98e9939768f7eb47933136b Mon Sep 17 00:00:00 2001 From: Andrey Dodonov Date: Tue, 22 Nov 2022 11:44:08 +0100 Subject: [PATCH 3/3] This is a ToDo which Zephyr should keep in mind with its frivolous casts back and forth between signed and unsigned. --- include/kernel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/kernel.h b/include/kernel.h index 59419549d9b4..c144a4052240 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1574,6 +1574,7 @@ __syscall int64_t k_uptime_ticks(void); */ static inline int64_t k_uptime_get(void) { + // ToDo casts: here and intern return k_ticks_to_ms_floor64(k_uptime_ticks()); }