aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2015-12-04 19:51:29 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-12-29 14:07:51 +0300
commit6bf5568f6371aeb55f4b719c39874531e272c4af (patch)
treebb3a4ac3f988bf6e56c28c225b9b11909c0f6e4a /platform
parentcd26cb0807221ed34858b9c660b49a75a0250997 (diff)
linux-generic: odp_time: don't use cpu cycle API to get time
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.savolainen@nokia.com> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> Conflicts: platform/linux-generic/Makefile.am platform/linux-generic/odp_time.c
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/Makefile.am1
-rw-r--r--platform/linux-generic/include/odp/plat/time_types.h6
-rw-r--r--platform/linux-generic/include/odp_cpu_internal.h29
-rw-r--r--platform/linux-generic/odp_cpu.c6
-rw-r--r--platform/linux-generic/odp_time.c105
5 files changed, 73 insertions, 74 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 71664c96c..50e76a2f6 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -102,7 +102,6 @@ noinst_HEADERS = \
${srcdir}/include/odp_schedule_internal.h \
${srcdir}/include/odp_spin_internal.h \
${srcdir}/include/odp_timer_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 9ba1508c7..e5765ec4c 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 664e2df5d..000000000
--- 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 636f811f8..4bd6a9a07 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 181d7323e..89bbf0c5a 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_sys_cpu_hz();
- 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_sys_cpu_hz();
+ 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};
}