diff mbox

[API-NEXT,v7,8/9] linux-generic: align with new wall time API

Message ID 1449251494-23210-9-git-send-email-ivan.khoronzhuk@linaro.org
State Accepted
Commit 1d03ed1857ef518a5c70a934897a508fb56ee943
Headers show

Commit Message

Ivan Khoronzhuk Dec. 4, 2015, 5:51 p.m. UTC
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>
---
 platform/linux-generic/include/odp_internal.h |  2 +
 platform/linux-generic/odp_init.c             |  4 ++
 platform/linux-generic/odp_schedule.c         |  9 ++--
 platform/linux-generic/odp_time.c             | 61 ++++++++++++++++++---------
 4 files changed, 49 insertions(+), 27 deletions(-)
diff mbox

Patch

diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index 74e48a9..49e23d9 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -79,6 +79,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);
+
 int odp_tm_init_global(void);
 
 void _odp_flush_caches(void);
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 7f35962..d93dab8 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 96b3ac5..3017876 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -586,7 +586,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;
 
@@ -604,15 +604,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 89bbf0c..1c7c214 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;
+}