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