From 1831431bab09ca248d91dc89d41827dab0f553d9 Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Wed, 22 Jun 2022 16:17:50 -0400 Subject: [PATCH] lib: posix: semaphore: use consistent timebase in sem_timedwait In the Zephyr implementation, `sem_timedwait()` uses a potentially wildly different timebase for comparison via `k_uptime_get()` (uptime in ms). The standard specifies `CLOCK_REALTIME`. However, the real-time clock can be modified to an arbitrary value via clock_settime() and there is no guarantee that it will always reflect uptime. This change ensures that `sem_timedwait()` uses a more consistent timebase for comparison. Fixes #46807 Signed-off-by: Christopher Friedt (cherry picked from commit 9d433c89a2f6c345f5b48a8e01777f76229cdcc1) --- lib/posix/Kconfig | 1 + lib/posix/semaphore.c | 7 ++++++- samples/net/sockets/socketpair/prj.conf | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index b1a0d52995b..2f6350d5b10 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -19,6 +19,7 @@ config POSIX_API config PTHREAD_IPC bool "POSIX pthread IPC API" default y if POSIX_API + depends on POSIX_CLOCK help This enables a mostly-standards-compliant implementation of the pthread mutex, condition variable and barrier IPC diff --git a/lib/posix/semaphore.c b/lib/posix/semaphore.c index 26a36f5c93a..3d60ddec8dd 100644 --- a/lib/posix/semaphore.c +++ b/lib/posix/semaphore.c @@ -91,6 +91,7 @@ int sem_post(sem_t *semaphore) int sem_timedwait(sem_t *semaphore, struct timespec *abstime) { int32_t timeout; + struct timespec current; int64_t current_ms, abstime_ms; __ASSERT(abstime, "abstime pointer NULL"); @@ -100,8 +101,12 @@ int sem_timedwait(sem_t *semaphore, struct timespec *abstime) return -1; } - current_ms = (int64_t)k_uptime_get(); + if (clock_gettime(CLOCK_REALTIME, ¤t) < 0) { + return -1; + } + abstime_ms = (int64_t)_ts_to_ms(abstime); + current_ms = (int64_t)_ts_to_ms(¤t); if (abstime_ms <= current_ms) { timeout = 0; diff --git a/samples/net/sockets/socketpair/prj.conf b/samples/net/sockets/socketpair/prj.conf index b884d633797..4f5d22d808b 100644 --- a/samples/net/sockets/socketpair/prj.conf +++ b/samples/net/sockets/socketpair/prj.conf @@ -12,4 +12,5 @@ CONFIG_TEST_RANDOM_GENERATOR=y # Use Portable threads CONFIG_PTHREAD_IPC=y +CONFIG_POSIX_CLOCK=y CONFIG_NET_SOCKETS_POSIX_NAMES=y