aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2015-11-06 15:08:55 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-11-25 16:28:54 +0300
commit44dde8a5c19a8dcdf6fb993fd47f6c7f208b1ba4 (patch)
tree374ae9a56c2736b92ac9730c2c7c3b63302192c2 /platform/linux-generic
parent9ba0ff81a33077472eea84670b45e85a8457ea23 (diff)
api: time: unbind CPU cycles from time API
Current time API supposes that frequency of counter is equal to CPU frequency. But that's not always true, for instance, in case if no access to CPU cycle counter, another hi-resolution timer can be used, and it`s rate can be different from CPU rate. There is no big difference in which cycles to measure time, the better hi-resolution timer the better measurements. So, unbind CPU cycle counter from time API by eliminating word "cycle" as it's believed to be used with CPU. Also add new opaque type for time odp_time_t, as it asks user to use API and abstracts time from units. New odp_time_t requires several additional API functions to be added: odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2); int odp_time_cmp(odp_time_t t1, odp_time_t t2); uint64_t odp_time_to_u64(odp_time_t hdl); Also added new definition that represents 0 ticks for time - ODP_TIME_NULL. It can be used instead of odp_time_from_ns(0) for comparison and initialization. This patch changes only used time API, it doesn't change used var names for simplicity. This time API can be implemented with local timer counter, so shouldn't be used between threads. Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> Reviewed-by: Petri Savolainen <petri.savolainen@nokia.com> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> Conflicts: platform/linux-generic/odp_time.c
Diffstat (limited to 'platform/linux-generic')
-rw-r--r--platform/linux-generic/Makefile.am1
-rw-r--r--platform/linux-generic/include/odp/plat/time_types.h36
-rw-r--r--platform/linux-generic/include/odp/time.h1
-rw-r--r--platform/linux-generic/odp_schedule.c16
-rw-r--r--platform/linux-generic/odp_time.c62
-rw-r--r--platform/linux-generic/odp_timer.c4
6 files changed, 99 insertions, 21 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 610e04d9e..70bd8fe85 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -70,6 +70,7 @@ odpplatinclude_HEADERS = \
$(srcdir)/include/odp/plat/strong_types.h \
$(srcdir)/include/odp/plat/thrmask_types.h \
$(srcdir)/include/odp/plat/ticketlock_types.h \
+ $(srcdir)/include/odp/plat/time_types.h \
$(srcdir)/include/odp/plat/timer_types.h \
$(srcdir)/include/odp/plat/version_types.h
diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h
new file mode 100644
index 000000000..9ba1508c7
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/time_types.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP time service
+ */
+
+#ifndef ODP_TIME_TYPES_H_
+#define ODP_TIME_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_time
+ * @{
+ **/
+
+typedef uint64_t odp_time_t;
+
+#define ODP_TIME_NULL ((odp_time_t)0)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/time.h b/platform/linux-generic/include/odp/time.h
index 3a3960b02..44e0d0d25 100644
--- a/platform/linux-generic/include/odp/time.h
+++ b/platform/linux-generic/include/odp/time.h
@@ -21,6 +21,7 @@ extern "C" {
+#include <odp/plat/time_types.h>
#include <odp/api/time.h>
#ifdef __cplusplus
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 5982f85a4..2a0e2c653 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -586,10 +586,10 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
odp_event_t out_ev[],
unsigned int max_num, unsigned int max_deq)
{
- uint64_t start_cycle, cycle, diff;
+ odp_time_t start_time, time, diff;
int ret;
- start_cycle = 0;
+ start_time = ODP_TIME_NULL;
while (1) {
ret = schedule(out_queue, out_ev, max_num, max_deq);
@@ -603,15 +603,15 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
if (wait == ODP_SCHED_NO_WAIT)
break;
- if (start_cycle == 0) {
- start_cycle = odp_time_cycles();
+ if (!odp_time_cmp(ODP_TIME_NULL, start_time)) {
+ start_time = odp_time_local();
continue;
}
- cycle = odp_time_cycles();
- diff = odp_time_diff_cycles(start_cycle, cycle);
+ time = odp_time_local();
+ diff = odp_time_diff(start_time, time);
- if (wait < diff)
+ if (odp_time_cmp(wait, diff) < 0)
break;
}
@@ -652,7 +652,7 @@ void odp_schedule_resume(void)
uint64_t odp_schedule_wait_time(uint64_t ns)
{
- return odp_time_ns_to_cycles(ns);
+ return odp_time_to_u64(odp_time_local_from_ns(ns));
}
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 74f802b83..a1494d76c 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -14,33 +14,73 @@
#define GIGA 1000000000
-uint64_t odp_time_cycles(void)
+static inline
+uint64_t time_to_tick(odp_time_t time)
{
- return odp_cpu_cycles();
+ return (uint64_t)time;
}
-uint64_t odp_time_diff_cycles(uint64_t t1, uint64_t t2)
+static inline
+odp_time_t tick_to_time(uint64_t tick)
{
- return _odp_cpu_cycles_diff(t1, t2);
+ return (odp_time_t)tick;
}
-uint64_t odp_time_cycles_to_ns(uint64_t cycles)
+odp_time_t odp_time_local(void)
+{
+ return tick_to_time(odp_cpu_cycles());
+}
+
+odp_time_t odp_time_diff(odp_time_t t1, odp_time_t t2)
+{
+ return tick_to_time(_odp_cpu_cycles_diff(t1, t2));
+}
+
+uint64_t odp_time_to_ns(odp_time_t time)
{
uint64_t hz = odp_sys_cpu_hz();
+ uint64_t tick = time_to_tick(time);
- if (cycles > (UINT64_MAX / GIGA))
- return (cycles/hz)*GIGA;
+ if (tick > (UINT64_MAX / GIGA))
+ return (tick / hz) * GIGA;
- return (cycles*GIGA)/hz;
+ return (tick * GIGA) / hz;
}
-uint64_t odp_time_ns_to_cycles(uint64_t ns)
+odp_time_t odp_time_local_from_ns(uint64_t ns)
{
uint64_t hz = odp_sys_cpu_hz();
if (ns > (UINT64_MAX / hz))
- return (ns/GIGA)*hz;
+ return tick_to_time((ns / GIGA) * hz);
+
+ return tick_to_time((ns * hz) / GIGA);
+}
+
+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);
- return (ns*hz)/GIGA;
+ if (tick1 < tick2)
+ return 1;
+
+ if (tick1 > tick2)
+ return -1;
+
+ return 0;
+}
+
+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);
+
+ return tick_to_time(tick1 + tick2);
+}
+
+uint64_t odp_time_to_u64(odp_time_t hdl)
+{
+ return time_to_tick(hdl);
}
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index e8f026744..bb32aa676 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -672,8 +672,8 @@ static void itimer_init(odp_timer_pool *tp)
strerror(errno));
res = tp->param.res_ns;
- sec = res / ODP_TIME_SEC;
- nsec = res - sec * ODP_TIME_SEC;
+ sec = res / ODP_TIME_SEC_IN_NS;
+ nsec = res - sec * ODP_TIME_SEC_IN_NS;
ispec.it_interval.tv_sec = (time_t)sec;
ispec.it_interval.tv_nsec = (long)nsec;