diff mbox

[API-NEXT,v5,1/6] api: time: add resolution and wait API calls

Message ID 1450440117-5588-2-git-send-email-ivan.khoronzhuk@linaro.org
State Accepted
Commit c51c91b0e4cd46fffda9ab6de7fcc3f52e895aae
Headers show

Commit Message

Ivan Khoronzhuk Dec. 18, 2015, 12:01 p.m. UTC
This patch adds odp_time_local_res() and odp_time_wait_until(),
odp_time_wait_ns() APIs.

Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
 include/odp/api/time.h            | 25 ++++++++++
 platform/linux-generic/odp_time.c | 98 ++++++++++++++++++++++++++++++---------
 2 files changed, 101 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/include/odp/api/time.h b/include/odp/api/time.h
index 9865d81..1f94710 100644
--- a/include/odp/api/time.h
+++ b/include/odp/api/time.h
@@ -101,6 +101,31 @@  odp_time_t odp_time_local_from_ns(uint64_t ns);
 int odp_time_cmp(odp_time_t t2, odp_time_t t1);
 
 /**
+ * Local time resolution in hertz
+ *
+ * @return      Local time resolution in hertz
+ */
+uint64_t odp_time_local_res(void);
+
+/**
+ * Wait until the specified (wall clock) time has been reached
+ *
+ * The thread potentially busy loop the entire wait time.
+ *
+ * @param time  Time to reach before continue
+ */
+void odp_time_wait_until(odp_time_t time);
+
+/**
+ * Wait the specified number of nanoseconds
+ *
+ * The thread potentially busy loop the entire wait time.
+ *
+ * @param ns    Time in nanoseconds to wait
+ */
+void odp_time_wait_ns(uint64_t ns);
+
+/**
  * Get printable value for an odp_time_t
  *
  * @param time time to be printed
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 9b64b37..a3ab2e3 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -29,8 +29,7 @@  uint64_t time_to_ns(odp_time_t time)
 	return ns;
 }
 
-static inline
-odp_time_t 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)
 {
 	odp_time_t time;
 
@@ -45,7 +44,7 @@  odp_time_t time_diff(odp_time_t t2, odp_time_t t1)
 	return time;
 }
 
-odp_time_t odp_time_local(void)
+static inline odp_time_t time_local(void)
 {
 	int ret;
 	_odp_time_t time;
@@ -57,17 +56,33 @@  odp_time_t odp_time_local(void)
 	return time_diff(time.ex, start_time);
 }
 
-odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
+static inline int time_cmp(odp_time_t t2, odp_time_t t1)
 {
-	return time_diff(t2, t1);
+	if (t2.tv_sec < t1.tv_sec)
+		return -1;
+
+	if (t2.tv_sec > t1.tv_sec)
+		return 1;
+
+	return t2.tv_nsec - t1.tv_nsec;
 }
 
-uint64_t odp_time_to_ns(odp_time_t time)
+static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2)
 {
-	return time_to_ns(time);
+	odp_time_t 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;
 }
 
-odp_time_t odp_time_local_from_ns(uint64_t ns)
+static inline odp_time_t time_local_from_ns(uint64_t ns)
 {
 	odp_time_t time;
 
@@ -77,30 +92,69 @@  odp_time_t odp_time_local_from_ns(uint64_t ns)
 	return time;
 }
 
-int odp_time_cmp(odp_time_t t2, odp_time_t t1)
+static inline void time_wait_until(odp_time_t time)
 {
-	if (t2.tv_sec < t1.tv_sec)
-		return -1;
+	odp_time_t cur;
 
-	if (t2.tv_sec > t1.tv_sec)
-		return 1;
+	do {
+		cur = time_local();
+	} while (time_cmp(time, cur) > 0);
+}
 
-	return t2.tv_nsec - t1.tv_nsec;
+odp_time_t odp_time_local(void)
+{
+	return time_local();
+}
+
+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)
+{
+	return time_local_from_ns(ns);
+}
+
+int odp_time_cmp(odp_time_t t2, odp_time_t t1)
+{
+	return time_cmp(t2, t1);
 }
 
 odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2)
 {
-	odp_time_t time;
+	return time_sum(t1, t2);
+}
 
-	time.tv_sec = t2.tv_sec + t1.tv_sec;
-	time.tv_nsec = t2.tv_nsec + t1.tv_nsec;
+uint64_t odp_time_local_res(void)
+{
+	int ret;
+	struct timespec tres;
 
-	if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) {
-		time.tv_nsec -= ODP_TIME_SEC_IN_NS;
-		++time.tv_sec;
-	}
+	ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres);
+	if (odp_unlikely(ret != 0))
+		ODP_ABORT("clock_getres failed\n");
 
-	return time;
+	return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
+}
+
+void odp_time_wait_ns(uint64_t ns)
+{
+	odp_time_t cur = time_local();
+	odp_time_t wait = time_local_from_ns(ns);
+	odp_time_t end_time = time_sum(cur, wait);
+
+	time_wait_until(end_time);
+}
+
+void odp_time_wait_until(odp_time_t time)
+{
+	return time_wait_until(time);
 }
 
 uint64_t odp_time_to_u64(odp_time_t time)