aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2015-12-04 19:51:33 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-12-29 14:07:51 +0300
commit9dd795ac7029812bda2c806e4f125247e3d15d54 (patch)
tree7361bf74e509fbd02a79ba107be12a8f3a2d3062
parentc1d945e6731f06da7b24de17fc7612cf239ee508 (diff)
linux-generic: align with new wall time API
The local time API supposes the time source is wall time. So correct linux-generic implementation. 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/include/odp_internal.h
-rw-r--r--platform/linux-generic/include/odp_internal.h2
-rw-r--r--platform/linux-generic/odp_init.c4
-rw-r--r--platform/linux-generic/odp_schedule.c9
-rw-r--r--platform/linux-generic/odp_time.c61
4 files changed, 49 insertions, 27 deletions
diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index 010b82f1f..113b7004d 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -77,6 +77,8 @@ int odp_schedule_term_local(void);
int odp_timer_init_global(void);
int odp_timer_disarm_all(void);
+int odp_time_global_init(void);
+
void _odp_flush_caches(void);
#ifdef __cplusplus
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 5e19d86c6..062095ab7 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -24,6 +24,10 @@ int odp_init_global(const odp_init_t *params,
odp_global_data.abort_fn = params->abort_fn;
}
+ if (odp_time_global_init()) {
+ ODP_ERR("ODP time init failed.\n");
+ return -1;
+ }
odp_system_info_init();
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index d8aa76abc..58f1b1b37 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -588,7 +588,7 @@ 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)
{
- odp_time_t start_time, time, diff, wtime;
+ odp_time_t next, wtime;
int first = 1;
int ret;
@@ -606,15 +606,12 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
if (first) {
wtime = odp_time_local_from_ns(wait);
- start_time = odp_time_local();
+ next = odp_time_sum(odp_time_local(), wtime);
first = 0;
continue;
}
- time = odp_time_local();
- diff = odp_time_diff(time, start_time);
-
- if (odp_time_cmp(wtime, diff) < 0)
+ if (odp_time_cmp(next, odp_time_local()) < 0)
break;
}
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 89bbf0c5a..1c7c21440 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -11,28 +11,24 @@
#include <odp/hints.h>
#include <odp_debug_internal.h>
-odp_time_t odp_time_local(void)
+static struct timespec start_time;
+
+static inline
+uint64_t time_to_ns(odp_time_t time)
{
- int ret;
- struct timespec time;
+ uint64_t ns;
- ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
- if (odp_unlikely(ret != 0))
- ODP_ABORT("clock_gettime failed\n");
+ ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
+ ns += time.tv_nsec;
- return time;
+ return ns;
}
-odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
+static inline
+odp_time_t time_diff(odp_time_t t2, odp_time_t 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;
@@ -44,14 +40,26 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
return time;
}
-uint64_t odp_time_to_ns(odp_time_t time)
+odp_time_t odp_time_local(void)
{
- uint64_t ns;
+ int ret;
+ struct timespec time;
- ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
- ns += time.tv_nsec;
+ ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+ if (odp_unlikely(ret != 0))
+ ODP_ABORT("clock_gettime failed\n");
- return ns;
+ return time_diff(time, start_time);
+}
+
+odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
+{
+ return time_diff(t2, t1);
+}
+
+uint64_t odp_time_to_ns(odp_time_t time)
+{
+ return time_to_ns(time);
}
odp_time_t odp_time_local_from_ns(uint64_t ns)
@@ -59,7 +67,7 @@ odp_time_t odp_time_local_from_ns(uint64_t ns)
struct timespec time;
time.tv_sec = ns / ODP_TIME_SEC_IN_NS;
- time.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
+ time.tv_nsec = ns - time.tv_sec * ODP_TIME_SEC_IN_NS;
return time;
}
@@ -102,10 +110,21 @@ uint64_t odp_time_to_u64(odp_time_t time)
resolution = (uint64_t)tres.tv_nsec;
- return odp_time_to_ns(time) / resolution;
+ return time_to_ns(time) / resolution;
}
odp_time_t odp_time_null(void)
{
return (struct timespec) {0, 0};
}
+
+int odp_time_global_init(void)
+{
+ int ret;
+ struct timespec time;
+
+ ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+ start_time = ret ? odp_time_null() : time;
+
+ return ret;
+}