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

Reply via email to