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.savolai...@linaro.org>
---
 .../include/odp/api/plat/time_types.h              |  32 ++---
 platform/linux-generic/odp_time.c                  | 143 ++++++---------------
 2 files changed, 52 insertions(+), 123 deletions(-)

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;
 }
-- 
2.11.0

Reply via email to