diff --git a/arch/posix/include/posix_cheats.h b/arch/posix/include/posix_cheats.h index 3ac977880c9..d05502ae3a5 100644 --- a/arch/posix/include/posix_cheats.h +++ b/arch/posix/include/posix_cheats.h @@ -31,6 +31,8 @@ #define pthread_barrier_t zap_pthread_barrier_t #define pthread_barrierattr_t zap_pthread_barrierattr_t #define pthread_attr_t zap_pthread_attr_t +#define clockid_t zap_clockid_t +#define sched_param zap_sched_param /* Condition variables */ #define pthread_cond_init(...) zap_pthread_cond_init(__VA_ARGS__) @@ -99,6 +101,10 @@ #define sleep(...) zap_sleep(__VA_ARGS__) #define usleep(...) zap_usleep(__VA_ARGS__) +/* Clock */ +#define clock_gettime(...) zap_clock_gettime(__VA_ARGS__) +#define clock_settime(...) zap_clock_settime(__VA_ARGS__) + #endif /* CONFIG_ARCH_POSIX */ #endif diff --git a/include/posix/pthread.h b/include/posix/pthread.h index 45e0d058483..2e9d3f83717 100644 --- a/include/posix/pthread.h +++ b/include/posix/pthread.h @@ -8,18 +8,7 @@ #define __PTHREAD_H__ #include -#ifdef CONFIG_NEWLIB_LIBC #include -#else -/* This should probably live somewhere else but Zephyr doesn't - * currently have a stdc layer to provide it - */ -struct timespec { - s32_t tv_sec; - s32_t tv_nsec; -}; -#endif /* CONFIG_NEWLIB_LIBC */ - #include "sys/types.h" #include "posix_sched.h" #include "unistd.h" @@ -63,11 +52,6 @@ struct posix_thread { #define PTHREAD_CANCEL_ENABLE (0 << _PTHREAD_CANCEL_POS) #define PTHREAD_CANCEL_DISABLE (1 << _PTHREAD_CANCEL_POS) -static inline s32_t _ts_to_ms(const struct timespec *to) -{ - return (to->tv_sec * 1000) + (to->tv_nsec / 1000000); -} - /** * @brief Declare a pthread condition variable * diff --git a/include/posix/sys/types.h b/include/posix/sys/types.h index aac7b4d46fb..c7d50d0358e 100644 --- a/include/posix/sys/types.h +++ b/include/posix/sys/types.h @@ -7,7 +7,6 @@ #ifndef __POSIX_TYPES_H__ #define __POSIX_TYPES_H__ - #ifdef __cplusplus extern "C" { #endif @@ -15,6 +14,7 @@ extern "C" { #include_next #ifdef CONFIG_PTHREAD_IPC +#include /* Thread attributes */ typedef struct pthread_attr_t { @@ -60,6 +60,9 @@ typedef struct pthread_barrierattr { } pthread_barrierattr_t; /* time related attributes */ +#ifndef CONFIG_NEWLIB_LIBC +typedef u32_t clockid_t; +#endif /*CONFIG_NEWLIB_LIBC */ typedef unsigned long useconds_t; #endif /* CONFIG_PTHREAD_IPC */ diff --git a/include/posix/time.h b/include/posix/time.h new file mode 100644 index 00000000000..150b52b3c21 --- /dev/null +++ b/include/posix/time.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __POSIX_TIME_H__ +#define __POSIX_TIME_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_NEWLIB_LIBC +#include_next +#else +struct timespec { + s32_t tv_sec; + s32_t tv_nsec; +}; +#endif /* CONFIG_NEWLIB_LIBC */ +#include +#include +#include "sys/types.h" + +#define CLOCK_MONOTONIC 1 + +static inline s32_t _ts_to_ms(const struct timespec *to) +{ + return (to->tv_sec * 1000) + (to->tv_nsec / 1000000); +} + +/** + * @brief Set clock time. + * + * See IEEE 1003.1 + */ +static inline int clock_settime(clockid_t clock_id, const struct timespec *ts) +{ + errno = ENOSYS; + return -1; +} + +int clock_gettime(clockid_t clock_id, struct timespec *ts); + +#ifdef __cplusplus +} +#endif + +#endif /* __POSIX_TIME_H__ */ diff --git a/kernel/posix/CMakeLists.txt b/kernel/posix/CMakeLists.txt index 853a6854a5e..8ee3df6c0fa 100644 --- a/kernel/posix/CMakeLists.txt +++ b/kernel/posix/CMakeLists.txt @@ -4,3 +4,4 @@ target_sources(kernel PRIVATE posix/pthread_mutex.c) target_sources(kernel PRIVATE posix/pthread_barrier.c) target_sources(kernel PRIVATE posix/pthread.c) target_sources(kernel PRIVATE posix/pthread_sched.c) +target_sources(kernel PRIVATE posix/clock.c) diff --git a/kernel/posix/clock.c b/kernel/posix/clock.c new file mode 100644 index 00000000000..d29d7853b78 --- /dev/null +++ b/kernel/posix/clock.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +/** + * @brief Get clock time specified by clock_id. + * + * See IEEE 1003.1 + */ +int clock_gettime(clockid_t clock_id, struct timespec *ts) +{ + s64_t elapsed_msecs, elapsed_secs; + s64_t elapsed_nsec, elapsed_cycles; + + if (clock_id != CLOCK_MONOTONIC) { + errno = EINVAL; + return -1; + } + + elapsed_msecs = k_uptime_get(); + elapsed_secs = elapsed_msecs / MSEC_PER_SEC; + + elapsed_cycles = (s64_t) (k_cycle_get_32() % + sys_clock_hw_cycles_per_sec); + elapsed_nsec = (s64_t) ((elapsed_cycles * NSEC_PER_SEC) / + sys_clock_hw_cycles_per_sec); + + ts->tv_sec = (s32_t) elapsed_secs; + ts->tv_nsec = (s32_t) elapsed_nsec; + return 0; +}