From 95a22b12174621aeba8ca3e0e61f7c66f03202bf Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Thu, 28 Dec 2023 01:43:52 -0500 Subject: [PATCH] posix: clock: clock_gettime() should not be a syscall We try to implement Zephyr's POSIX API as regular library functions, so remove the __syscall annotation from clock_gettime() and implement the syscall portion of it under the hood. This also adds a bit of a micro-optimization in that we can do a lot of processing outside of the system call. In fact, processing CLOCK_MONOTONIC likely does not require any syscall other than k_uptime_ticks(). Signed-off-by: Christopher Friedt --- include/zephyr/posix/time.h | 8 ------ lib/posix/CMakeLists.txt | 2 +- lib/posix/clock.c | 50 ++++++++++++++++++++++++++----------- lib/posix/posix_clock.h | 19 ++++++++++++++ 4 files changed, 56 insertions(+), 23 deletions(-) create mode 100644 lib/posix/posix_clock.h diff --git a/include/zephyr/posix/time.h b/include/zephyr/posix/time.h index 85cb7f8ae4226a..ea7e68cb079e97 100644 --- a/include/zephyr/posix/time.h +++ b/include/zephyr/posix/time.h @@ -82,11 +82,7 @@ static inline int32_t _ts_to_ms(const struct timespec *to) return (to->tv_sec * MSEC_PER_SEC) + (to->tv_nsec / NSEC_PER_MSEC); } -#if defined(CONFIG_ARCH_POSIX) && defined(CONFIG_EXTERNAL_LIBC) int clock_gettime(clockid_t clock_id, struct timespec *ts); -#else -__syscall int clock_gettime(clockid_t clock_id, struct timespec *ts); -#endif /* CONFIG_ARCH_POSIX */ int clock_settime(clockid_t clock_id, const struct timespec *ts); /* Timer APIs */ int timer_create(clockid_t clockId, struct sigevent *evp, timer_t *timerid); @@ -103,10 +99,6 @@ int clock_nanosleep(clockid_t clock_id, int flags, } #endif -#if !(defined(CONFIG_ARCH_POSIX) && defined(CONFIG_EXTERNAL_LIBC)) -#include -#endif /* CONFIG_ARCH_POSIX */ - #else /* ZEPHYR_INCLUDE_POSIX_TIME_H_ */ /* Read the toolchain header when finds itself on the * first attempt. diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index c6b3a88aeab4a9..e73c78d40e4297 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -3,7 +3,7 @@ set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) zephyr_syscall_header( - ${ZEPHYR_BASE}/include/zephyr/posix/time.h + posix_clock.h ) zephyr_interface_library_named(posix_subsys) diff --git a/lib/posix/clock.c b/lib/posix/clock.c index 9fef8586b4883d..0d085a6d0d00c9 100644 --- a/lib/posix/clock.c +++ b/lib/posix/clock.c @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "posix_clock.h" + #include #include #include @@ -25,10 +28,40 @@ static struct k_spinlock rt_clock_base_lock; * * See IEEE 1003.1 */ -int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) +int z_impl___posix_clock_get_base(clockid_t clock_id, struct timespec *base) +{ + switch (clock_id) { + case CLOCK_MONOTONIC: + base->tv_sec = 0; + base->tv_nsec = 0; + break; + + case CLOCK_REALTIME: + K_SPINLOCK(&rt_clock_base_lock) { + *base = rt_clock_base; + } + break; + + default: + errno = EINVAL; + return -1; + } + + return 0; +} + +#ifdef CONFIG_USERSPACE +int z_vrfy___posix_clock_get_base(clockid_t clock_id, struct timespec *ts) +{ + K_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); + return z_impl___posix_clock_get_base(clock_id, ts); +} +#include +#endif + +int clock_gettime(clockid_t clock_id, struct timespec *ts) { struct timespec base; - k_spinlock_key_t key; switch (clock_id) { case CLOCK_MONOTONIC: @@ -37,9 +70,7 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) break; case CLOCK_REALTIME: - key = k_spin_lock(&rt_clock_base_lock); - base = rt_clock_base; - k_spin_unlock(&rt_clock_base_lock, key); + (void)__posix_clock_get_base(clock_id, &base); break; default: @@ -65,15 +96,6 @@ int z_impl_clock_gettime(clockid_t clock_id, struct timespec *ts) return 0; } -#ifdef CONFIG_USERSPACE -int z_vrfy_clock_gettime(clockid_t clock_id, struct timespec *ts) -{ - K_OOPS(K_SYSCALL_MEMORY_WRITE(ts, sizeof(*ts))); - return z_impl_clock_gettime(clock_id, ts); -} -#include -#endif - /** * @brief Set the time of the specified clock. * diff --git a/lib/posix/posix_clock.h b/lib/posix/posix_clock.h new file mode 100644 index 00000000000000..a665f4ce06d90e --- /dev/null +++ b/lib/posix/posix_clock.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_POSIX_POSIX_CLOCK_H_ +#define ZEPHYR_LIB_POSIX_POSIX_CLOCK_H_ + +#include + +#include +#include + +__syscall int __posix_clock_get_base(clockid_t clock_id, struct timespec *ts); + +#include + +#endif