Skip to content

Commit

Permalink
posix: clock: clock_gettime() should not be a syscall
Browse files Browse the repository at this point in the history
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 <cfriedt@meta.com>
  • Loading branch information
cfriedt authored and stephanosio committed Jan 3, 2024
1 parent e0383a6 commit 95a22b1
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 23 deletions.
8 changes: 0 additions & 8 deletions include/zephyr/posix/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -103,10 +99,6 @@ int clock_nanosleep(clockid_t clock_id, int flags,
}
#endif

#if !(defined(CONFIG_ARCH_POSIX) && defined(CONFIG_EXTERNAL_LIBC))
#include <syscalls/time.h>
#endif /* CONFIG_ARCH_POSIX */

#else /* ZEPHYR_INCLUDE_POSIX_TIME_H_ */
/* Read the toolchain header when <posix/time.h> finds itself on the
* first attempt.
Expand Down
2 changes: 1 addition & 1 deletion lib/posix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
50 changes: 36 additions & 14 deletions lib/posix/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "posix_clock.h"

#include <zephyr/kernel.h>
#include <errno.h>
#include <zephyr/posix/time.h>
Expand All @@ -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 <syscalls/__posix_clock_get_base_mrsh.c>
#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:
Expand All @@ -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:
Expand All @@ -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 <syscalls/clock_gettime_mrsh.c>
#endif

/**
* @brief Set the time of the specified clock.
*
Expand Down
19 changes: 19 additions & 0 deletions lib/posix/posix_clock.h
Original file line number Diff line number Diff line change
@@ -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 <time.h>

#include <zephyr/kernel.h>
#include <zephyr/posix/posix_types.h>

__syscall int __posix_clock_get_base(clockid_t clock_id, struct timespec *ts);

#include <syscalls/posix_clock.h>

#endif

0 comments on commit 95a22b1

Please sign in to comment.