[API-NEXT,v3,11/11] linux-gen: time: store timespec as nsec

Message ID 20170428120958.17526-12-petri.savolainen@linaro.org
State Accepted
Commit dfbab7438c8404d5f4af20086e2100d40a5ffc0c
Headers show
Series
  • Use HW time counter
Related show

Commit Message

Petri Savolainen April 28, 2017, 12:09 p.m.
Use single 64 bit nanosecond value to store time when using
posix time. Posix time stamp is converted directly from
timespec (sec + nsec) to nsec time. Storage space for odp_time_t
is halved as both posix and HW time use single u64. Some
functions (sum, diff, cmp) are generic for both time sources.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>

---
 .../include/odp/api/plat/time_types.h              |  32 ++---
 platform/linux-generic/odp_time.c                  | 143 ++++++---------------
 2 files changed, 52 insertions(+), 123 deletions(-)

-- 
2.11.0

Patch hide | download patch | download mbox

diff --git a/platform/linux-generic/include/odp/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h
index 1cafb1f7..71e354e6 100644
--- a/platform/linux-generic/include/odp/api/plat/time_types.h
+++ b/platform/linux-generic/include/odp/api/plat/time_types.h
@@ -22,32 +22,24 @@  extern "C" {
  **/
 
 /**
- * @internal Time structure used to isolate odp-linux implementation from
- * the linux timespec structure, which is dependent on POSIX extension level.
+ * @internal Time structure used for both POSIX timespec and HW counter
+ * implementations.
  */
 typedef struct odp_time_t {
 	union {
-		/** @internal Posix timespec */
-		struct {
-			/** @internal Seconds */
-			int64_t tv_sec;
-
-			/** @internal Nanoseconds */
-			int64_t tv_nsec;
-		} spec;
-
-		/** @internal HW time counter */
-		struct {
-			/** @internal Counter value */
-			uint64_t count;
-
-			/** @internal Reserved */
-			uint64_t reserved;
-		} hw;
+		/** @internal Used with generic 64 bit operations */
+		uint64_t u64;
+
+		/** @internal Nanoseconds */
+		uint64_t nsec;
+
+		/** @internal HW timer counter value */
+		uint64_t count;
+
 	};
 } odp_time_t;
 
-#define ODP_TIME_NULL ((odp_time_t){.spec = {0, 0} })
+#define ODP_TIME_NULL ((odp_time_t){.u64 = 0})
 
 /**
  * @}
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index ac82175d..2bbe5666 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -15,10 +15,10 @@ 
 #include <inttypes.h>
 
 typedef struct time_global_t {
-	odp_time_t start_time;
-	int        use_hw;
-	uint64_t   hw_start;
-	uint64_t   hw_freq_hz;
+	struct timespec spec_start;
+	int             use_hw;
+	uint64_t        hw_start;
+	uint64_t        hw_freq_hz;
 } time_global_t;
 
 static time_global_t global;
@@ -27,19 +27,23 @@  static time_global_t global;
  * Posix timespec based functions
  */
 
-static inline odp_time_t time_spec_diff(odp_time_t t2, odp_time_t t1)
+static inline uint64_t time_spec_diff_nsec(struct timespec *t2,
+					   struct timespec *t1)
 {
-	odp_time_t time;
+	struct timespec diff;
+	uint64_t nsec;
 
-	time.spec.tv_sec = t2.spec.tv_sec - t1.spec.tv_sec;
-	time.spec.tv_nsec = t2.spec.tv_nsec - t1.spec.tv_nsec;
+	diff.tv_sec  = t2->tv_sec  - t1->tv_sec;
+	diff.tv_nsec = t2->tv_nsec - t1->tv_nsec;
 
-	if (time.spec.tv_nsec < 0) {
-		time.spec.tv_nsec += ODP_TIME_SEC_IN_NS;
-		--time.spec.tv_sec;
+	if (diff.tv_nsec < 0) {
+		diff.tv_nsec += ODP_TIME_SEC_IN_NS;
+		diff.tv_sec  -= 1;
 	}
 
-	return time;
+	nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec;
+
+	return nsec;
 }
 
 static inline odp_time_t time_spec_cur(void)
@@ -52,10 +56,9 @@  static inline odp_time_t time_spec_cur(void)
 	if (odp_unlikely(ret != 0))
 		ODP_ABORT("clock_gettime failed\n");
 
-	time.spec.tv_sec = sys_time.tv_sec;
-	time.spec.tv_nsec = sys_time.tv_nsec;
+	time.nsec = time_spec_diff_nsec(&sys_time, &global.spec_start);
 
-	return time_spec_diff(time, global.start_time);
+	return time;
 }
 
 static inline uint64_t time_spec_res(void)
@@ -70,48 +73,16 @@  static inline uint64_t time_spec_res(void)
 	return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
 }
 
-static inline int time_spec_cmp(odp_time_t t2, odp_time_t t1)
-{
-	if (t2.spec.tv_sec < t1.spec.tv_sec)
-		return -1;
-
-	if (t2.spec.tv_sec > t1.spec.tv_sec)
-		return 1;
-
-	return t2.spec.tv_nsec - t1.spec.tv_nsec;
-}
-
-static inline odp_time_t time_spec_sum(odp_time_t t1, odp_time_t t2)
-{
-	odp_time_t time;
-
-	time.spec.tv_sec = t2.spec.tv_sec + t1.spec.tv_sec;
-	time.spec.tv_nsec = t2.spec.tv_nsec + t1.spec.tv_nsec;
-
-	if (time.spec.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) {
-		time.spec.tv_nsec -= ODP_TIME_SEC_IN_NS;
-		++time.spec.tv_sec;
-	}
-
-	return time;
-}
-
 static inline uint64_t time_spec_to_ns(odp_time_t time)
 {
-	uint64_t ns;
-
-	ns = time.spec.tv_sec * ODP_TIME_SEC_IN_NS;
-	ns += time.spec.tv_nsec;
-
-	return ns;
+	return time.nsec;
 }
 
 static inline odp_time_t time_spec_from_ns(uint64_t ns)
 {
 	odp_time_t time;
 
-	time.spec.tv_sec = ns / ODP_TIME_SEC_IN_NS;
-	time.spec.tv_nsec = ns - time.spec.tv_sec * ODP_TIME_SEC_IN_NS;
+	time.nsec = ns;
 
 	return time;
 }
@@ -124,7 +95,7 @@  static inline odp_time_t time_hw_cur(void)
 {
 	odp_time_t time;
 
-	time.hw.count = cpu_global_time() - global.hw_start;
+	time.count = cpu_global_time() - global.hw_start;
 
 	return time;
 }
@@ -136,40 +107,11 @@  static inline uint64_t time_hw_res(void)
 	return global.hw_freq_hz / 10;
 }
 
-static inline int time_hw_cmp(odp_time_t t2, odp_time_t t1)
-{
-	if (odp_likely(t2.hw.count > t1.hw.count))
-		return 1;
-
-	if (t2.hw.count < t1.hw.count)
-		return -1;
-
-	return 0;
-}
-
-static inline odp_time_t time_hw_diff(odp_time_t t2, odp_time_t t1)
-{
-	odp_time_t time;
-
-	time.hw.count = t2.hw.count - t1.hw.count;
-
-	return time;
-}
-
-static inline odp_time_t time_hw_sum(odp_time_t t1, odp_time_t t2)
-{
-	odp_time_t time;
-
-	time.hw.count = t1.hw.count + t2.hw.count;
-
-	return time;
-}
-
 static inline uint64_t time_hw_to_ns(odp_time_t time)
 {
 	uint64_t nsec;
 	uint64_t freq_hz = global.hw_freq_hz;
-	uint64_t count = time.hw.count;
+	uint64_t count = time.count;
 	uint64_t sec = 0;
 
 	if (count >= freq_hz) {
@@ -197,8 +139,7 @@  static inline odp_time_t time_hw_from_ns(uint64_t ns)
 	count  = sec * freq_hz;
 	count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS;
 
-	time.hw.reserved = 0;
-	time.hw.count = count;
+	time.count = count;
 
 	return time;
 }
@@ -225,26 +166,22 @@  static inline uint64_t time_res(void)
 
 static inline int time_cmp(odp_time_t t2, odp_time_t t1)
 {
-	if (global.use_hw)
-		return time_hw_cmp(t2, t1);
-
-	return time_spec_cmp(t2, t1);
-}
+	if (odp_likely(t2.u64 > t1.u64))
+		return 1;
 
-static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1)
-{
-	if (global.use_hw)
-		return time_hw_diff(t2, t1);
+	if (t2.u64 < t1.u64)
+		return -1;
 
-	return time_spec_diff(t2, t1);
+	return 0;
 }
 
 static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2)
 {
-	if (global.use_hw)
-		return time_hw_sum(t1, t2);
+	odp_time_t time;
+
+	time.u64 = t1.u64 + t2.u64;
 
-	return time_spec_sum(t1, t2);
+	return time;
 }
 
 static inline uint64_t time_to_ns(odp_time_t time)
@@ -284,7 +221,11 @@  odp_time_t odp_time_global(void)
 
 odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
 {
-	return time_diff(t2, t1);
+	odp_time_t time;
+
+	time.u64 = t2.u64 - t1.u64;
+
+	return time;
 }
 
 uint64_t odp_time_to_ns(odp_time_t time)
@@ -338,7 +279,6 @@  void odp_time_wait_until(odp_time_t time)
 
 int odp_time_init_global(void)
 {
-	struct timespec sys_time;
 	int ret = 0;
 
 	memset(&global, 0, sizeof(time_global_t));
@@ -357,13 +297,10 @@  int odp_time_init_global(void)
 		return 0;
 	}
 
-	global.start_time = ODP_TIME_NULL;
+	global.spec_start.tv_sec  = 0;
+	global.spec_start.tv_nsec = 0;
 
-	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time);
-	if (ret == 0) {
-		global.start_time.spec.tv_sec  = sys_time.tv_sec;
-		global.start_time.spec.tv_nsec = sys_time.tv_nsec;
-	}
+	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &global.spec_start);
 
 	return ret;
 }