The linux-generic time API implementation shouldn't depend on cpu cycle API wich is not stable enough to measure time period due to dynamic frequency scaling.
Reviewed-by: Petri Savolainen <petri.savolai...@nokia.com> Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> --- platform/linux-generic/Makefile.am | 1 - .../linux-generic/include/odp/plat/time_types.h | 6 +- platform/linux-generic/include/odp_cpu_internal.h | 29 ------ platform/linux-generic/odp_cpu.c | 6 +- platform/linux-generic/odp_time.c | 105 +++++++++++++-------- 5 files changed, 73 insertions(+), 74 deletions(-) delete mode 100644 platform/linux-generic/include/odp_cpu_internal.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 102f11e..ba220c0 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -110,7 +110,6 @@ noinst_HEADERS = \ ${srcdir}/include/odp_timer_internal.h \ ${srcdir}/include/odp_timer_wheel_internal.h \ ${srcdir}/include/odp_traffic_mngr_internal.h \ - ${srcdir}/include/odp_cpu_internal.h \ ${srcdir}/Makefile.inc __LIB__libodp_la_SOURCES = \ diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h index 9ba1508..e5765ec 100644 --- a/platform/linux-generic/include/odp/plat/time_types.h +++ b/platform/linux-generic/include/odp/plat/time_types.h @@ -21,9 +21,11 @@ extern "C" { * @{ **/ -typedef uint64_t odp_time_t; +typedef struct timespec odp_time_t; -#define ODP_TIME_NULL ((odp_time_t)0) +odp_time_t odp_time_null(void); + +#define ODP_TIME_NULL odp_time_null() /** * @} diff --git a/platform/linux-generic/include/odp_cpu_internal.h b/platform/linux-generic/include/odp_cpu_internal.h deleted file mode 100644 index 664e2df..0000000 --- a/platform/linux-generic/include/odp_cpu_internal.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef ODP_CPU_INTERNAL_H_ -#define ODP_CPU_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <odp/cpu.h> - -static inline -uint64_t _odp_cpu_cycles_diff(uint64_t c2, uint64_t c1) -{ - if (odp_likely(c2 >= c1)) - return c2 - c1; - - return c2 + (odp_cpu_cycles_max() - c1) + 1; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-generic/odp_cpu.c b/platform/linux-generic/odp_cpu.c index 636f811..4bd6a9a 100644 --- a/platform/linux-generic/odp_cpu.c +++ b/platform/linux-generic/odp_cpu.c @@ -6,9 +6,11 @@ #include <odp/cpu.h> #include <odp/hints.h> -#include <odp_cpu_internal.h> uint64_t odp_cpu_cycles_diff(uint64_t c2, uint64_t c1) { - return _odp_cpu_cycles_diff(c2, c1); + if (odp_likely(c2 >= c1)) + return c2 - c1; + + return c2 + (odp_cpu_cycles_max() - c1) + 1; } diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index a2e4046..89bbf0c 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -6,81 +6,106 @@ #define _POSIX_C_SOURCE 200809L +#include <time.h> #include <odp/time.h> #include <odp/hints.h> -#include <odp/system_info.h> -#include <odp/cpu.h> -#include <odp_cpu_internal.h> +#include <odp_debug_internal.h> -#define GIGA 1000000000 - -static inline -uint64_t time_to_tick(odp_time_t time) +odp_time_t odp_time_local(void) { - return (uint64_t)time; -} + int ret; + struct timespec time; -static inline -odp_time_t tick_to_time(uint64_t tick) -{ - return (odp_time_t)tick; -} + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_gettime failed\n"); -odp_time_t odp_time_local(void) -{ - return tick_to_time(odp_cpu_cycles()); + return time; } odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) { - return tick_to_time(_odp_cpu_cycles_diff(t2, t1)); + uint64_t ns1, ns2; + struct timespec time; + + ns1 = odp_time_to_ns(t1); + ns2 = odp_time_to_ns(t2); + if (ns2 < ns1) + return (struct timespec) {0, 1}; + + time.tv_sec = t2.tv_sec - t1.tv_sec; + time.tv_nsec = t2.tv_nsec - t1.tv_nsec; + + if (time.tv_nsec < 0) { + time.tv_nsec += ODP_TIME_SEC_IN_NS; + --time.tv_sec; + } + + return time; } uint64_t odp_time_to_ns(odp_time_t time) { - uint64_t hz = odp_cpu_hz_max(); - uint64_t tick = time_to_tick(time); + uint64_t ns; - if (tick > (UINT64_MAX / GIGA)) - return (tick / hz) * GIGA; + ns = time.tv_sec * ODP_TIME_SEC_IN_NS; + ns += time.tv_nsec; - return (tick * GIGA) / hz; + return ns; } - odp_time_t odp_time_local_from_ns(uint64_t ns) { - uint64_t hz = odp_cpu_hz_max(); + struct timespec time; - if (ns > (UINT64_MAX / hz)) - return tick_to_time((ns / GIGA) * hz); + time.tv_sec = ns / ODP_TIME_SEC_IN_NS; + time.tv_nsec = ns % ODP_TIME_SEC_IN_NS; - return tick_to_time((ns * hz) / GIGA); + return time; } int odp_time_cmp(odp_time_t t2, odp_time_t t1) { - uint64_t tick1 = time_to_tick(t1); - uint64_t tick2 = time_to_tick(t2); + if (t2.tv_sec < t1.tv_sec) + return -1; - if (tick1 < tick2) + if (t2.tv_sec > t1.tv_sec) return 1; - if (tick1 > tick2) - return -1; - - return 0; + return t2.tv_nsec - t1.tv_nsec; } odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) { - uint64_t tick1 = time_to_tick(t1); - uint64_t tick2 = time_to_tick(t2); + struct timespec time; + + time.tv_sec = t2.tv_sec + t1.tv_sec; + time.tv_nsec = t2.tv_nsec + t1.tv_nsec; + + if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { + time.tv_nsec -= ODP_TIME_SEC_IN_NS; + ++time.tv_sec; + } + + return time; +} + +uint64_t odp_time_to_u64(odp_time_t time) +{ + int ret; + struct timespec tres; + uint64_t resolution; + + ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_getres failed\n"); + + resolution = (uint64_t)tres.tv_nsec; - return tick_to_time(tick1 + tick2); + return odp_time_to_ns(time) / resolution; } -uint64_t odp_time_to_u64(odp_time_t hdl) +odp_time_t odp_time_null(void) { - return time_to_tick(hdl); + return (struct timespec) {0, 0}; } -- 1.9.1 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp