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 <chrisfriedt@gmail.com>
(cherry picked from commit 9d433c89a2)
This commit is contained in:
Christopher Friedt 2022-06-22 16:17:50 -04:00
parent 765f63c6b9
commit 1831431bab
3 changed files with 8 additions and 1 deletions

View File

@ -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

View File

@ -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, &current) < 0) {
return -1;
}
abstime_ms = (int64_t)_ts_to_ms(abstime);
current_ms = (int64_t)_ts_to_ms(&current);
if (abstime_ms <= current_ms) {
timeout = 0;

View File

@ -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