diff mbox

[lng,API-NEXT,v2,7/7] api: time: make local time to be wall time

Message ID 1447350305-3254-8-git-send-email-ivan.khoronzhuk@linaro.org
State New
Headers show

Commit Message

Ivan Khoronzhuk Nov. 12, 2015, 5:45 p.m. UTC
It's more convenient the local time to be a wall time. It's allows
to measure time beginning from start of the thread. This allows to use
local time in similar manner as it's supposed to be used with global
time and the 64-bit timer is enough to guarantee it.
Correct validation test to check new time API.

Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
 example/generator/odp_generator.c                  |  2 +-
 include/odp/api/time.h                             | 30 ++++++++--
 .../linux-generic/include/odp/plat/time_types.h    |  4 +-
 platform/linux-generic/include/odp_internal.h      |  2 +
 platform/linux-generic/odp_schedule.c              |  2 +-
 platform/linux-generic/odp_time.c                  | 58 ++++++++++++++++---
 test/performance/odp_pktio_perf.c                  | 24 ++++----
 test/validation/pktio/pktio.c                      |  4 +-
 test/validation/scheduler/scheduler.c              |  2 +-
 test/validation/time/time.c                        | 67 +++++++++++++++-------
 10 files changed, 143 insertions(+), 52 deletions(-)

Comments

Ivan Khoronzhuk Nov. 13, 2015, 9:28 a.m. UTC | #1
Petri,

Additional API calls like resolution and delay can be added after this patch.
The global API can be added after this patch and it will be absolutely similar
except global time source (in linux-generic it's the same source).

I've added this patch separately (not considering that series became to long) in
order to be able simply modify it and highlight the wall time difference.
Read my short clarification below.

On 12.11.15 19:45, Ivan Khoronzhuk wrote:
> It's more convenient the local time to be a wall time. It's allows
> to measure time beginning from start of the thread. This allows to use
> local time in similar manner as it's supposed to be used with global
> time and the 64-bit timer is enough to guarantee it.
> Correct validation test to check new time API.
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
> ---
>   example/generator/odp_generator.c                  |  2 +-
>   include/odp/api/time.h                             | 30 ++++++++--
>   .../linux-generic/include/odp/plat/time_types.h    |  4 +-
>   platform/linux-generic/include/odp_internal.h      |  2 +
>   platform/linux-generic/odp_schedule.c              |  2 +-
>   platform/linux-generic/odp_time.c                  | 58 ++++++++++++++++---
>   test/performance/odp_pktio_perf.c                  | 24 ++++----
>   test/validation/pktio/pktio.c                      |  4 +-
>   test/validation/scheduler/scheduler.c              |  2 +-
>   test/validation/time/time.c                        | 67 +++++++++++++++-------
>   10 files changed, 143 insertions(+), 52 deletions(-)
>
> diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
> index 2de530d..ddae7c0 100644
> --- a/example/generator/odp_generator.c
> +++ b/example/generator/odp_generator.c
> @@ -594,7 +594,7 @@ static void print_global_stats(int num_workers)
>   	while (odp_thrmask_worker(&thrd_mask) < num_workers)
>   		continue;
>
> -	wait = odp_time_local_from_ns(verbose_interval * ODP_TIME_SEC_IN_NS);
> +	wait = odp_time_local_val(verbose_interval * ODP_TIME_SEC_IN_NS);
>   	next = odp_time_sum(odp_time_local(), wait);
>
>   	while (odp_thrmask_worker(&thrd_mask) == num_workers) {
> diff --git a/include/odp/api/time.h b/include/odp/api/time.h
> index 3228879..9a5916b 100644
> --- a/include/odp/api/time.h
> +++ b/include/odp/api/time.h
> @@ -37,15 +37,16 @@ extern "C" {
>    */
>
>   /**
> - * @def ODP_TIME_NULL
> - * Zero time stamp
> + * @def ODP_TIME_NULL_VAL
> + * Zero time interval
>    */
>
>   /**
>    * Current local time
>    *
>    * Returns current local time stamp value. The local time source provides high
> - * resolution time and is monotonic.
> + * resolution time and is monotonic. The local time is wall time that means it's
> + * local for each thread.
>    *
>    * @return Local time stamp.
>    */
> @@ -57,7 +58,9 @@ odp_time_t odp_time_local(void);
>    * @param t2    Second time stamp
>    * @param t1    First time stamp
>    *
> - * @return Difference of time stamps
> + * @return Difference of time stamps ot intervals. Diff of timestamp and
> + * interval results in timestamp.
> + *
>    */
>   odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>
> @@ -68,6 +71,9 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>    * @param t2    Time stamp
>    *
>    * @return Sum of time stamps
> + *
> + * @note Sum of two timestamp shouldn't be used, only timestamp and interval or
> + * two intervals. Sum of timestamp and interval results in timestamp.
>    */
>   odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
>
> @@ -90,12 +96,28 @@ uint64_t odp_time_to_ns(odp_time_t time);
>   odp_time_t odp_time_local_from_ns(uint64_t ns);
>
>   /**
> + * Convert nanoseconds to interval of local time
> + *
> + * @param ns	Time in nanoseconds
> + */
> +odp_time_t odp_time_local_val(uint64_t ns);

This call is added to simplify process of getting time interval.
W/o this call no another way to get time interval except:

t1 = odp_time_local();
ns1 = odp_time_to_ns(t1);
ns2 = ns1 + ns;
t2 = odp_time_local();
dt = odp_time_diff(t2, t1);

And it must be done even if t2 or t1 is not needed in the program.
It can be replaced on simple function:

dt = odp_time_local_val(ns);

> +
> +/**
> + * Convert time interval to nanoseconds
> + *
> + * @param val	Time interval
> + */
> +uint64_t odp_time_val_to_ns(odp_time_t val);

This call is added to allow to not differentiate time interval and timestamp in the implementation.
It can be deleted but in this case implementation should every time control "interval flag".

The "interval flag" can be generated from APIs like:
odp_time_diff()         // depending on arguments result will be timestamp or time interval
odp_time_local_val()    // generates time interval
odp_time_sum()          // depending on arguments result will be timestamp or time interval
odp_time_local()        // generates timestamp
ODP_TIME_NULL_VAL       // generates time interval (used as start point in integrating time intervals)

but in this case implementation thinks about "interval flag" and check it in every API call.
Whith odp_time_val_to_ns() call no need in this.
If you like this variant w/o this call, I can delete it.

> +
> +/**
>    * Compare two times
>    *
>    * @param t2    Second time
>    * @param t1    First time
>    *
>    * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1
> + *
> + * @note Compare two timestamps or two intervals
>    */
>   int odp_time_cmp(odp_time_t t2, odp_time_t t1);
>
> diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h
> index e5765ec..ccf6580 100644
> --- a/platform/linux-generic/include/odp/plat/time_types.h
> +++ b/platform/linux-generic/include/odp/plat/time_types.h
> @@ -23,9 +23,9 @@ extern "C" {
>
>   typedef struct timespec odp_time_t;
>
> -odp_time_t odp_time_null(void);
> +odp_time_t odp_time_null_val(void);
>
> -#define ODP_TIME_NULL	odp_time_null()
> +#define ODP_TIME_NULL_VAL	odp_time_null_val()
>
>   /**
>    * @}
> diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
> index 14ba159..baff135 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_local_init(void);
> +
>   void _odp_flush_caches(void);
>
>   #ifdef __cplusplus
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
> index 3017876..6a3440c 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -603,7 +603,7 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
>   			break;
>
>   		if (first) {
> -			wtime = odp_time_local_from_ns(wait);
> +			wtime = odp_time_local_val(wait);
>   			next = odp_time_sum(odp_time_local(), wtime);
>   			first = 0;
>   			continue;
> diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
> index 73b2dcb..c82f974 100644
> --- a/platform/linux-generic/odp_time.c
> +++ b/platform/linux-generic/odp_time.c
> @@ -11,6 +11,30 @@
>   #include <odp/hints.h>
>   #include <odp_debug_internal.h>
>
> +static __thread uint64_t start_local_ns;
> +
> +static inline
> +odp_time_t _odp_time_local_val(uint64_t ns)
> +{
> +	struct timespec val;
> +
> +	val.tv_sec = ns / ODP_TIME_SEC_IN_NS;
> +	val.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
> +
> +	return val;
> +}
> +
> +static inline
> +uint64_t _odp_time_val_to_ns(odp_time_t val)
> +{
> +	uint64_t ns;
> +
> +	ns = val.tv_sec * ODP_TIME_SEC_IN_NS;
> +	ns += val.tv_nsec;
> +
> +	return ns;
> +}
> +
>   odp_time_t odp_time_local(void)
>   {
>   	int ret;
> @@ -38,24 +62,30 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
>   	return time;
>   }
>
> +uint64_t odp_time_val_to_ns(odp_time_t val)
> +{
> +	return _odp_time_val_to_ns(val);
> +}
> +
>   uint64_t odp_time_to_ns(odp_time_t time)
>   {
>   	uint64_t ns;
>
> -	ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
> -	ns += time.tv_nsec;
> +	ns = _odp_time_val_to_ns(time);
> +	ns -= start_local_ns;
>
>   	return ns;
>   }
>
>   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;
> +	ns += start_local_ns;
> +	return _odp_time_local_val(ns);
> +}
>
> -	return time;
> +odp_time_t odp_time_local_val(uint64_t ns)
> +{
> +	return _odp_time_local_val(ns);
>   }
>
>   int odp_time_cmp(odp_time_t t2, odp_time_t t1)
> @@ -96,11 +126,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 _odp_time_val_to_ns(time) / resolution;
>   }
>
> -odp_time_t odp_time_null(void)
> +odp_time_t odp_time_null_val(void)
>   {
>   	return (struct timespec) {0, 0};
>   }
>
> +int odp_time_local_init(void)
> +{
> +	int ret;
> +	struct timespec time;
> +
> +	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
> +	start_local_ns = ret ? 0 : _odp_time_val_to_ns(time);
> +
> +	return ret;
> +}
> diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c
> index 3d37ae1..e1f65e4 100644
> --- a/test/performance/odp_pktio_perf.c
> +++ b/test/performance/odp_pktio_perf.c
> @@ -310,7 +310,7 @@ static void *run_thread_tx(void *arg)
>   	uint32_t batch_len;
>   	int unsent_pkts = 0;
>   	odp_event_t  tx_event[BATCH_LEN_MAX];
> -	odp_time_t idle_start = ODP_TIME_NULL;
> +	odp_time_t idle_start = ODP_TIME_NULL_VAL;
>
>   	thread_args_t *targs = arg;
>
> @@ -328,10 +328,10 @@ static void *run_thread_tx(void *arg)
>   	if (outq == ODP_QUEUE_INVALID)
>   		LOG_ABORT("Failed to get output queue for thread %d\n", thr_id);
>
> -	burst_gap = odp_time_local_from_ns(
> +	burst_gap = odp_time_local_val(
>   			ODP_TIME_SEC_IN_NS / (targs->pps / targs->batch_len));
>   	send_duration =
> -		odp_time_local_from_ns(targs->duration * ODP_TIME_SEC_IN_NS);
> +		odp_time_local_val(targs->duration * ODP_TIME_SEC_IN_NS);
>
>   	odp_barrier_wait(&globals->tx_barrier);
>
> @@ -343,18 +343,18 @@ static void *run_thread_tx(void *arg)
>
>   		if (odp_time_cmp(burst_gap_end, cur_time) > 0) {
>   			cur_time = odp_time_local();
> -			if (!odp_time_cmp(idle_start, ODP_TIME_NULL))
> +			if (!odp_time_cmp(idle_start, ODP_TIME_NULL_VAL))
>   				idle_start = cur_time;
>   			continue;
>   		}
>
> -		if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) {
> +		if (odp_time_cmp(idle_start, ODP_TIME_NULL_VAL) > 0) {
>   			odp_time_t diff = odp_time_diff(cur_time, idle_start);
>
>   			stats->s.idle_ticks =
>   				odp_time_sum(diff, stats->s.idle_ticks);
>
> -			idle_start = ODP_TIME_NULL;
> +			idle_start = ODP_TIME_NULL_VAL;
>   		}
>
>   		burst_gap_end = odp_time_sum(burst_gap_end, burst_gap);
> @@ -375,7 +375,7 @@ static void *run_thread_tx(void *arg)
>   	       " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
>   	       thr_id, stats->s.tx_cnt,
>   	       stats->s.enq_failures, stats->s.alloc_failures,
> -	       odp_time_to_ns(stats->s.idle_ticks) /
> +	       odp_time_val_to_ns(stats->s.idle_ticks) /
>   	       (uint64_t)ODP_TIME_MSEC_IN_NS);
>
>   	return NULL;
> @@ -595,13 +595,13 @@ static int setup_txrx_masks(odp_cpumask_t *thd_mask_tx,
>    */
>   static void busy_loop_ns(uint64_t wait_ns)
>   {
> -	odp_time_t diff;
> -	odp_time_t start_time = odp_time_local();
> -	odp_time_t wait = odp_time_local_from_ns(wait_ns);
> +	odp_time_t wait = odp_time_local_val(wait_ns);
> +	odp_time_t cur = odp_time_local();
> +	odp_time_t end_time = odp_time_sum(cur, wait);
>
>   	do {
> -		diff = odp_time_diff(odp_time_local(), start_time);
> -	} while (odp_time_cmp(wait, diff) > 0);
> +		cur = odp_time_local();
> +	} while (odp_time_cmp(end_time, cur) > 0);
>   }
>
>   /*
> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
> index aee3a7d..6d7e954 100644
> --- a/test/validation/pktio/pktio.c
> +++ b/test/validation/pktio/pktio.c
> @@ -339,7 +339,7 @@ static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
>   	odp_time_t wait, end;
>   	odp_event_t ev;
>
> -	wait = odp_time_local_from_ns(ns);
> +	wait = odp_time_local_val(ns);
>   	end = odp_time_sum(odp_time_local(), wait);
>   	do {
>   		ev = odp_queue_deq(queue);
> @@ -359,7 +359,7 @@ static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
>   	uint64_t wait;
>
>   	wait = odp_schedule_wait_time(ns);
> -	wait_time = odp_time_local_from_ns(ns);
> +	wait_time = odp_time_local_val(ns);
>   	end = odp_time_sum(odp_time_local(), wait_time);
>   	do {
>   		pkt = ODP_PACKET_INVALID;
> diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c
> index a562a8a..58f93e0 100644
> --- a/test/validation/scheduler/scheduler.c
> +++ b/test/validation/scheduler/scheduler.c
> @@ -718,7 +718,7 @@ static void *schedule_common_(void *arg)
>   			CU_ASSERT(from != ODP_QUEUE_INVALID);
>   			if (locked) {
>   				int cnt;
> -				odp_time_t time = ODP_TIME_NULL;
> +				odp_time_t time = ODP_TIME_NULL_VAL;
>   				/* Do some work here to keep the thread busy */
>   				for (cnt = 0; cnt < 1000; cnt++)
>   					time = odp_time_sum(time,
> diff --git a/test/validation/time/time.c b/test/validation/time/time.c
> index 8f5dfe6..4386c34 100644
> --- a/test/validation/time/time.c
> +++ b/test/validation/time/time.c
> @@ -18,6 +18,7 @@ void time_test_odp_conversion(void)
>   	odp_time_t time;
>   	uint64_t upper_limit, lower_limit;
>
> +	/* test timestamp conversions */
>   	ns1 = 100;
>   	time = odp_time_local_from_ns(ns1);
>
> @@ -34,8 +35,18 @@ void time_test_odp_conversion(void)
>
>   	ns2 = odp_time_to_ns(time);
>
> -	/* need to check within arithmetic tolerance that the same
> -	 * value in ns is returned after conversions */
> +	/*
> +	 * need to check within arithmetic tolerance that the same
> +	 * value in ns is returned after conversions
> +	 */
> +	upper_limit = ns1 + TOLERANCE;
> +	lower_limit = ns1 - TOLERANCE;
> +	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
> +
> +	/* test time vals conversions */
> +	time = odp_time_local_val(ns1);
> +	ns2 = odp_time_val_to_ns(time);
> +
>   	upper_limit = ns1 + TOLERANCE;
>   	lower_limit = ns1 - TOLERANCE;
>   	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
> @@ -75,6 +86,7 @@ void time_test_odp_cmp(void)
>   	volatile int count = 0;
>   	odp_time_t t1, t2, t3;
>
> +	/* test compare of timestamps */
>   	t1 = odp_time_local();
>
>   	while (count < BUSY_LOOP_CNT) {
> @@ -105,8 +117,23 @@ void time_test_odp_cmp(void)
>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>   	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>
> -	t1 = odp_time_local_from_ns(0);
> -	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0);
> +	t1 = odp_time_local_val(0);
> +	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL_VAL) == 0);
> +
> +	/* test compare of time intervals */
> +	t1 = odp_time_local_val(15);
> +	t2 = odp_time_local_val(23);
> +	t3 = odp_time_local_val(51);
> +
> +	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
> +	CU_ASSERT(odp_time_cmp(t3, t2) > 0);
> +	CU_ASSERT(odp_time_cmp(t3, t1) > 0);
> +	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
> +	CU_ASSERT(odp_time_cmp(t2, t3) < 0);
> +	CU_ASSERT(odp_time_cmp(t1, t3) < 0);
> +	CU_ASSERT(odp_time_cmp(t1, t1) == 0);
> +	CU_ASSERT(odp_time_cmp(t2, t2) == 0);
> +	CU_ASSERT(odp_time_cmp(t3, t3) == 0);
>   }
>
>   /* check that a time difference gives a reasonable result */
> @@ -129,12 +156,12 @@ void time_test_odp_diff(void)
>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>
>   	diff = odp_time_diff(t2, t1);
> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>
>   	ns1 = odp_time_to_ns(t1);
>   	ns2 = odp_time_to_ns(t2);
>   	ns = ns2 - ns1;
> -	nsdiff = odp_time_to_ns(diff);
> +	nsdiff = odp_time_val_to_ns(diff);
>
>   	upper_limit = ns + TOLERANCE;
>   	lower_limit = ns - TOLERANCE;
> @@ -142,11 +169,11 @@ void time_test_odp_diff(void)
>
>   	/* test timestamp and interval diff */
>   	ns1 = 54;
> -	t1 = odp_time_local_from_ns(ns1);
> +	t1 = odp_time_local_val(ns1);
>   	ns = ns2 - ns1;
>
>   	diff = odp_time_diff(t2, t1);
> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>   	nsdiff = odp_time_to_ns(diff);
>
>   	upper_limit = ns + TOLERANCE;
> @@ -157,10 +184,10 @@ void time_test_odp_diff(void)
>   	ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS;
>   	ns = ns2 - ns1;
>
> -	t2 = odp_time_local_from_ns(ns2);
> +	t2 = odp_time_local_val(ns2);
>   	diff = odp_time_diff(t2, t1);
> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
> -	nsdiff = odp_time_to_ns(diff);
> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
> +	nsdiff = odp_time_val_to_ns(diff);
>
>   	upper_limit = ns + TOLERANCE;
>   	lower_limit = ns - TOLERANCE;
> @@ -168,9 +195,9 @@ void time_test_odp_diff(void)
>
>   	/* same time has to diff to 0 */
>   	diff = odp_time_diff(t2, t2);
> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0);
> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) == 0);
>
> -	diff = odp_time_diff(t2, ODP_TIME_NULL);
> +	diff = odp_time_diff(t2, ODP_TIME_NULL_VAL);
>   	CU_ASSERT(odp_time_cmp(t2, diff) == 0);
>   }
>
> @@ -184,12 +211,12 @@ void time_test_odp_sum(void)
>   	/* sum timestamp and interval */
>   	t1 = odp_time_local();
>   	ns2 = 103;
> -	t2 = odp_time_local_from_ns(ns2);
> +	t2 = odp_time_local_val(ns2);
>   	ns1 = odp_time_to_ns(t1);
>   	ns = ns1 + ns2;
>
>   	sum = odp_time_sum(t2, t1);
> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>   	nssum = odp_time_to_ns(sum);
>
>   	upper_limit = ns + TOLERANCE;
> @@ -198,19 +225,19 @@ void time_test_odp_sum(void)
>
>   	/* sum intervals */
>   	ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS;
> -	t1 = odp_time_local_from_ns(ns1);
> +	t1 = odp_time_local_val(ns1);
>   	ns = ns1 + ns2;
>
>   	sum = odp_time_sum(t2, t1);
> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
> -	nssum = odp_time_to_ns(sum);
> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
> +	nssum = odp_time_val_to_ns(sum);
>
>   	upper_limit = ns + TOLERANCE;
>   	lower_limit = ns - TOLERANCE;
>   	CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit));
>
>   	/* test on 0 */
> -	sum = odp_time_sum(t2, ODP_TIME_NULL);
> +	sum = odp_time_sum(t2, ODP_TIME_NULL_VAL);
>   	CU_ASSERT(odp_time_cmp(t2, sum) == 0);
>   }
>
> @@ -235,7 +262,7 @@ void time_test_odp_to_u64(void)
>
>   	CU_ASSERT(val2 > val1);
>
> -	val1 = odp_time_to_u64(ODP_TIME_NULL);
> +	val1 = odp_time_to_u64(ODP_TIME_NULL_VAL);
>   	CU_ASSERT(val1 == 0);
>   }
>
>
Ivan Khoronzhuk Nov. 19, 2015, 10:50 a.m. UTC | #2
ping.

On 13.11.15 11:28, Ivan Khoronzhuk wrote:
> Petri,
>
> Additional API calls like resolution and delay can be added after this patch.
> The global API can be added after this patch and it will be absolutely similar
> except global time source (in linux-generic it's the same source).
>
> I've added this patch separately (not considering that series became to long) in
> order to be able simply modify it and highlight the wall time difference.
> Read my short clarification below.
>
> On 12.11.15 19:45, Ivan Khoronzhuk wrote:
>> It's more convenient the local time to be a wall time. It's allows
>> to measure time beginning from start of the thread. This allows to use
>> local time in similar manner as it's supposed to be used with global
>> time and the 64-bit timer is enough to guarantee it.
>> Correct validation test to check new time API.
>>
>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> ---
>>   example/generator/odp_generator.c                  |  2 +-
>>   include/odp/api/time.h                             | 30 ++++++++--
>>   .../linux-generic/include/odp/plat/time_types.h    |  4 +-
>>   platform/linux-generic/include/odp_internal.h      |  2 +
>>   platform/linux-generic/odp_schedule.c              |  2 +-
>>   platform/linux-generic/odp_time.c                  | 58 ++++++++++++++++---
>>   test/performance/odp_pktio_perf.c                  | 24 ++++----
>>   test/validation/pktio/pktio.c                      |  4 +-
>>   test/validation/scheduler/scheduler.c              |  2 +-
>>   test/validation/time/time.c                        | 67 +++++++++++++++-------
>>   10 files changed, 143 insertions(+), 52 deletions(-)
>>
>> diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
>> index 2de530d..ddae7c0 100644
>> --- a/example/generator/odp_generator.c
>> +++ b/example/generator/odp_generator.c
>> @@ -594,7 +594,7 @@ static void print_global_stats(int num_workers)
>>       while (odp_thrmask_worker(&thrd_mask) < num_workers)
>>           continue;
>>
>> -    wait = odp_time_local_from_ns(verbose_interval * ODP_TIME_SEC_IN_NS);
>> +    wait = odp_time_local_val(verbose_interval * ODP_TIME_SEC_IN_NS);
>>       next = odp_time_sum(odp_time_local(), wait);
>>
>>       while (odp_thrmask_worker(&thrd_mask) == num_workers) {
>> diff --git a/include/odp/api/time.h b/include/odp/api/time.h
>> index 3228879..9a5916b 100644
>> --- a/include/odp/api/time.h
>> +++ b/include/odp/api/time.h
>> @@ -37,15 +37,16 @@ extern "C" {
>>    */
>>
>>   /**
>> - * @def ODP_TIME_NULL
>> - * Zero time stamp
>> + * @def ODP_TIME_NULL_VAL
>> + * Zero time interval
>>    */
>>
>>   /**
>>    * Current local time
>>    *
>>    * Returns current local time stamp value. The local time source provides high
>> - * resolution time and is monotonic.
>> + * resolution time and is monotonic. The local time is wall time that means it's
>> + * local for each thread.
>>    *
>>    * @return Local time stamp.
>>    */
>> @@ -57,7 +58,9 @@ odp_time_t odp_time_local(void);
>>    * @param t2    Second time stamp
>>    * @param t1    First time stamp
>>    *
>> - * @return Difference of time stamps
>> + * @return Difference of time stamps ot intervals. Diff of timestamp and
>> + * interval results in timestamp.
>> + *
>>    */
>>   odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>
>> @@ -68,6 +71,9 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>    * @param t2    Time stamp
>>    *
>>    * @return Sum of time stamps
>> + *
>> + * @note Sum of two timestamp shouldn't be used, only timestamp and interval or
>> + * two intervals. Sum of timestamp and interval results in timestamp.
>>    */
>>   odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
>>
>> @@ -90,12 +96,28 @@ uint64_t odp_time_to_ns(odp_time_t time);
>>   odp_time_t odp_time_local_from_ns(uint64_t ns);
>>
>>   /**
>> + * Convert nanoseconds to interval of local time
>> + *
>> + * @param ns    Time in nanoseconds
>> + */
>> +odp_time_t odp_time_local_val(uint64_t ns);
>
> This call is added to simplify process of getting time interval.
> W/o this call no another way to get time interval except:
>
> t1 = odp_time_local();
> ns1 = odp_time_to_ns(t1);
> ns2 = ns1 + ns;
> t2 = odp_time_local();
> dt = odp_time_diff(t2, t1);
>
> And it must be done even if t2 or t1 is not needed in the program.
> It can be replaced on simple function:
>
> dt = odp_time_local_val(ns);
>
>> +
>> +/**
>> + * Convert time interval to nanoseconds
>> + *
>> + * @param val    Time interval
>> + */
>> +uint64_t odp_time_val_to_ns(odp_time_t val);
>
> This call is added to allow to not differentiate time interval and timestamp in the implementation.
> It can be deleted but in this case implementation should every time control "interval flag".
>
> The "interval flag" can be generated from APIs like:
> odp_time_diff()         // depending on arguments result will be timestamp or time interval
> odp_time_local_val()    // generates time interval
> odp_time_sum()          // depending on arguments result will be timestamp or time interval
> odp_time_local()        // generates timestamp
> ODP_TIME_NULL_VAL       // generates time interval (used as start point in integrating time intervals)
>
> but in this case implementation thinks about "interval flag" and check it in every API call.
> Whith odp_time_val_to_ns() call no need in this.
> If you like this variant w/o this call, I can delete it.
>
>> +
>> +/**
>>    * Compare two times
>>    *
>>    * @param t2    Second time
>>    * @param t1    First time
>>    *
>>    * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1
>> + *
>> + * @note Compare two timestamps or two intervals
>>    */
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1);
>>
>> diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h
>> index e5765ec..ccf6580 100644
>> --- a/platform/linux-generic/include/odp/plat/time_types.h
>> +++ b/platform/linux-generic/include/odp/plat/time_types.h
>> @@ -23,9 +23,9 @@ extern "C" {
>>
>>   typedef struct timespec odp_time_t;
>>
>> -odp_time_t odp_time_null(void);
>> +odp_time_t odp_time_null_val(void);
>>
>> -#define ODP_TIME_NULL    odp_time_null()
>> +#define ODP_TIME_NULL_VAL    odp_time_null_val()
>>
>>   /**
>>    * @}
>> diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
>> index 14ba159..baff135 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_local_init(void);
>> +
>>   void _odp_flush_caches(void);
>>
>>   #ifdef __cplusplus
>> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
>> index 3017876..6a3440c 100644
>> --- a/platform/linux-generic/odp_schedule.c
>> +++ b/platform/linux-generic/odp_schedule.c
>> @@ -603,7 +603,7 @@ static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
>>               break;
>>
>>           if (first) {
>> -            wtime = odp_time_local_from_ns(wait);
>> +            wtime = odp_time_local_val(wait);
>>               next = odp_time_sum(odp_time_local(), wtime);
>>               first = 0;
>>               continue;
>> diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
>> index 73b2dcb..c82f974 100644
>> --- a/platform/linux-generic/odp_time.c
>> +++ b/platform/linux-generic/odp_time.c
>> @@ -11,6 +11,30 @@
>>   #include <odp/hints.h>
>>   #include <odp_debug_internal.h>
>>
>> +static __thread uint64_t start_local_ns;
>> +
>> +static inline
>> +odp_time_t _odp_time_local_val(uint64_t ns)
>> +{
>> +    struct timespec val;
>> +
>> +    val.tv_sec = ns / ODP_TIME_SEC_IN_NS;
>> +    val.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
>> +
>> +    return val;
>> +}
>> +
>> +static inline
>> +uint64_t _odp_time_val_to_ns(odp_time_t val)
>> +{
>> +    uint64_t ns;
>> +
>> +    ns = val.tv_sec * ODP_TIME_SEC_IN_NS;
>> +    ns += val.tv_nsec;
>> +
>> +    return ns;
>> +}
>> +
>>   odp_time_t odp_time_local(void)
>>   {
>>       int ret;
>> @@ -38,24 +62,30 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
>>       return time;
>>   }
>>
>> +uint64_t odp_time_val_to_ns(odp_time_t val)
>> +{
>> +    return _odp_time_val_to_ns(val);
>> +}
>> +
>>   uint64_t odp_time_to_ns(odp_time_t time)
>>   {
>>       uint64_t ns;
>>
>> -    ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
>> -    ns += time.tv_nsec;
>> +    ns = _odp_time_val_to_ns(time);
>> +    ns -= start_local_ns;
>>
>>       return ns;
>>   }
>>
>>   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;
>> +    ns += start_local_ns;
>> +    return _odp_time_local_val(ns);
>> +}
>>
>> -    return time;
>> +odp_time_t odp_time_local_val(uint64_t ns)
>> +{
>> +    return _odp_time_local_val(ns);
>>   }
>>
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1)
>> @@ -96,11 +126,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 _odp_time_val_to_ns(time) / resolution;
>>   }
>>
>> -odp_time_t odp_time_null(void)
>> +odp_time_t odp_time_null_val(void)
>>   {
>>       return (struct timespec) {0, 0};
>>   }
>>
>> +int odp_time_local_init(void)
>> +{
>> +    int ret;
>> +    struct timespec time;
>> +
>> +    ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
>> +    start_local_ns = ret ? 0 : _odp_time_val_to_ns(time);
>> +
>> +    return ret;
>> +}
>> diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c
>> index 3d37ae1..e1f65e4 100644
>> --- a/test/performance/odp_pktio_perf.c
>> +++ b/test/performance/odp_pktio_perf.c
>> @@ -310,7 +310,7 @@ static void *run_thread_tx(void *arg)
>>       uint32_t batch_len;
>>       int unsent_pkts = 0;
>>       odp_event_t  tx_event[BATCH_LEN_MAX];
>> -    odp_time_t idle_start = ODP_TIME_NULL;
>> +    odp_time_t idle_start = ODP_TIME_NULL_VAL;
>>
>>       thread_args_t *targs = arg;
>>
>> @@ -328,10 +328,10 @@ static void *run_thread_tx(void *arg)
>>       if (outq == ODP_QUEUE_INVALID)
>>           LOG_ABORT("Failed to get output queue for thread %d\n", thr_id);
>>
>> -    burst_gap = odp_time_local_from_ns(
>> +    burst_gap = odp_time_local_val(
>>               ODP_TIME_SEC_IN_NS / (targs->pps / targs->batch_len));
>>       send_duration =
>> -        odp_time_local_from_ns(targs->duration * ODP_TIME_SEC_IN_NS);
>> +        odp_time_local_val(targs->duration * ODP_TIME_SEC_IN_NS);
>>
>>       odp_barrier_wait(&globals->tx_barrier);
>>
>> @@ -343,18 +343,18 @@ static void *run_thread_tx(void *arg)
>>
>>           if (odp_time_cmp(burst_gap_end, cur_time) > 0) {
>>               cur_time = odp_time_local();
>> -            if (!odp_time_cmp(idle_start, ODP_TIME_NULL))
>> +            if (!odp_time_cmp(idle_start, ODP_TIME_NULL_VAL))
>>                   idle_start = cur_time;
>>               continue;
>>           }
>>
>> -        if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) {
>> +        if (odp_time_cmp(idle_start, ODP_TIME_NULL_VAL) > 0) {
>>               odp_time_t diff = odp_time_diff(cur_time, idle_start);
>>
>>               stats->s.idle_ticks =
>>                   odp_time_sum(diff, stats->s.idle_ticks);
>>
>> -            idle_start = ODP_TIME_NULL;
>> +            idle_start = ODP_TIME_NULL_VAL;
>>           }
>>
>>           burst_gap_end = odp_time_sum(burst_gap_end, burst_gap);
>> @@ -375,7 +375,7 @@ static void *run_thread_tx(void *arg)
>>              " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
>>              thr_id, stats->s.tx_cnt,
>>              stats->s.enq_failures, stats->s.alloc_failures,
>> -           odp_time_to_ns(stats->s.idle_ticks) /
>> +           odp_time_val_to_ns(stats->s.idle_ticks) /
>>              (uint64_t)ODP_TIME_MSEC_IN_NS);
>>
>>       return NULL;
>> @@ -595,13 +595,13 @@ static int setup_txrx_masks(odp_cpumask_t *thd_mask_tx,
>>    */
>>   static void busy_loop_ns(uint64_t wait_ns)
>>   {
>> -    odp_time_t diff;
>> -    odp_time_t start_time = odp_time_local();
>> -    odp_time_t wait = odp_time_local_from_ns(wait_ns);
>> +    odp_time_t wait = odp_time_local_val(wait_ns);
>> +    odp_time_t cur = odp_time_local();
>> +    odp_time_t end_time = odp_time_sum(cur, wait);
>>
>>       do {
>> -        diff = odp_time_diff(odp_time_local(), start_time);
>> -    } while (odp_time_cmp(wait, diff) > 0);
>> +        cur = odp_time_local();
>> +    } while (odp_time_cmp(end_time, cur) > 0);
>>   }
>>
>>   /*
>> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
>> index aee3a7d..6d7e954 100644
>> --- a/test/validation/pktio/pktio.c
>> +++ b/test/validation/pktio/pktio.c
>> @@ -339,7 +339,7 @@ static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
>>       odp_time_t wait, end;
>>       odp_event_t ev;
>>
>> -    wait = odp_time_local_from_ns(ns);
>> +    wait = odp_time_local_val(ns);
>>       end = odp_time_sum(odp_time_local(), wait);
>>       do {
>>           ev = odp_queue_deq(queue);
>> @@ -359,7 +359,7 @@ static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
>>       uint64_t wait;
>>
>>       wait = odp_schedule_wait_time(ns);
>> -    wait_time = odp_time_local_from_ns(ns);
>> +    wait_time = odp_time_local_val(ns);
>>       end = odp_time_sum(odp_time_local(), wait_time);
>>       do {
>>           pkt = ODP_PACKET_INVALID;
>> diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c
>> index a562a8a..58f93e0 100644
>> --- a/test/validation/scheduler/scheduler.c
>> +++ b/test/validation/scheduler/scheduler.c
>> @@ -718,7 +718,7 @@ static void *schedule_common_(void *arg)
>>               CU_ASSERT(from != ODP_QUEUE_INVALID);
>>               if (locked) {
>>                   int cnt;
>> -                odp_time_t time = ODP_TIME_NULL;
>> +                odp_time_t time = ODP_TIME_NULL_VAL;
>>                   /* Do some work here to keep the thread busy */
>>                   for (cnt = 0; cnt < 1000; cnt++)
>>                       time = odp_time_sum(time,
>> diff --git a/test/validation/time/time.c b/test/validation/time/time.c
>> index 8f5dfe6..4386c34 100644
>> --- a/test/validation/time/time.c
>> +++ b/test/validation/time/time.c
>> @@ -18,6 +18,7 @@ void time_test_odp_conversion(void)
>>       odp_time_t time;
>>       uint64_t upper_limit, lower_limit;
>>
>> +    /* test timestamp conversions */
>>       ns1 = 100;
>>       time = odp_time_local_from_ns(ns1);
>>
>> @@ -34,8 +35,18 @@ void time_test_odp_conversion(void)
>>
>>       ns2 = odp_time_to_ns(time);
>>
>> -    /* need to check within arithmetic tolerance that the same
>> -     * value in ns is returned after conversions */
>> +    /*
>> +     * need to check within arithmetic tolerance that the same
>> +     * value in ns is returned after conversions
>> +     */
>> +    upper_limit = ns1 + TOLERANCE;
>> +    lower_limit = ns1 - TOLERANCE;
>> +    CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> +
>> +    /* test time vals conversions */
>> +    time = odp_time_local_val(ns1);
>> +    ns2 = odp_time_val_to_ns(time);
>> +
>>       upper_limit = ns1 + TOLERANCE;
>>       lower_limit = ns1 - TOLERANCE;
>>       CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> @@ -75,6 +86,7 @@ void time_test_odp_cmp(void)
>>       volatile int count = 0;
>>       odp_time_t t1, t2, t3;
>>
>> +    /* test compare of timestamps */
>>       t1 = odp_time_local();
>>
>>       while (count < BUSY_LOOP_CNT) {
>> @@ -105,8 +117,23 @@ void time_test_odp_cmp(void)
>>       CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>       CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>>
>> -    t1 = odp_time_local_from_ns(0);
>> -    CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0);
>> +    t1 = odp_time_local_val(0);
>> +    CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL_VAL) == 0);
>> +
>> +    /* test compare of time intervals */
>> +    t1 = odp_time_local_val(15);
>> +    t2 = odp_time_local_val(23);
>> +    t3 = odp_time_local_val(51);
>> +
>> +    CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>> +    CU_ASSERT(odp_time_cmp(t3, t2) > 0);
>> +    CU_ASSERT(odp_time_cmp(t3, t1) > 0);
>> +    CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>> +    CU_ASSERT(odp_time_cmp(t2, t3) < 0);
>> +    CU_ASSERT(odp_time_cmp(t1, t3) < 0);
>> +    CU_ASSERT(odp_time_cmp(t1, t1) == 0);
>> +    CU_ASSERT(odp_time_cmp(t2, t2) == 0);
>> +    CU_ASSERT(odp_time_cmp(t3, t3) == 0);
>>   }
>>
>>   /* check that a time difference gives a reasonable result */
>> @@ -129,12 +156,12 @@ void time_test_odp_diff(void)
>>       CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>
>>       diff = odp_time_diff(t2, t1);
>> -    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>
>>       ns1 = odp_time_to_ns(t1);
>>       ns2 = odp_time_to_ns(t2);
>>       ns = ns2 - ns1;
>> -    nsdiff = odp_time_to_ns(diff);
>> +    nsdiff = odp_time_val_to_ns(diff);
>>
>>       upper_limit = ns + TOLERANCE;
>>       lower_limit = ns - TOLERANCE;
>> @@ -142,11 +169,11 @@ void time_test_odp_diff(void)
>>
>>       /* test timestamp and interval diff */
>>       ns1 = 54;
>> -    t1 = odp_time_local_from_ns(ns1);
>> +    t1 = odp_time_local_val(ns1);
>>       ns = ns2 - ns1;
>>
>>       diff = odp_time_diff(t2, t1);
>> -    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>       nsdiff = odp_time_to_ns(diff);
>>
>>       upper_limit = ns + TOLERANCE;
>> @@ -157,10 +184,10 @@ void time_test_odp_diff(void)
>>       ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS;
>>       ns = ns2 - ns1;
>>
>> -    t2 = odp_time_local_from_ns(ns2);
>> +    t2 = odp_time_local_val(ns2);
>>       diff = odp_time_diff(t2, t1);
>> -    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> -    nsdiff = odp_time_to_ns(diff);
>> +    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>> +    nsdiff = odp_time_val_to_ns(diff);
>>
>>       upper_limit = ns + TOLERANCE;
>>       lower_limit = ns - TOLERANCE;
>> @@ -168,9 +195,9 @@ void time_test_odp_diff(void)
>>
>>       /* same time has to diff to 0 */
>>       diff = odp_time_diff(t2, t2);
>> -    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0);
>> +    CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) == 0);
>>
>> -    diff = odp_time_diff(t2, ODP_TIME_NULL);
>> +    diff = odp_time_diff(t2, ODP_TIME_NULL_VAL);
>>       CU_ASSERT(odp_time_cmp(t2, diff) == 0);
>>   }
>>
>> @@ -184,12 +211,12 @@ void time_test_odp_sum(void)
>>       /* sum timestamp and interval */
>>       t1 = odp_time_local();
>>       ns2 = 103;
>> -    t2 = odp_time_local_from_ns(ns2);
>> +    t2 = odp_time_local_val(ns2);
>>       ns1 = odp_time_to_ns(t1);
>>       ns = ns1 + ns2;
>>
>>       sum = odp_time_sum(t2, t1);
>> -    CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> +    CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>>       nssum = odp_time_to_ns(sum);
>>
>>       upper_limit = ns + TOLERANCE;
>> @@ -198,19 +225,19 @@ void time_test_odp_sum(void)
>>
>>       /* sum intervals */
>>       ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS;
>> -    t1 = odp_time_local_from_ns(ns1);
>> +    t1 = odp_time_local_val(ns1);
>>       ns = ns1 + ns2;
>>
>>       sum = odp_time_sum(t2, t1);
>> -    CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> -    nssum = odp_time_to_ns(sum);
>> +    CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>> +    nssum = odp_time_val_to_ns(sum);
>>
>>       upper_limit = ns + TOLERANCE;
>>       lower_limit = ns - TOLERANCE;
>>       CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit));
>>
>>       /* test on 0 */
>> -    sum = odp_time_sum(t2, ODP_TIME_NULL);
>> +    sum = odp_time_sum(t2, ODP_TIME_NULL_VAL);
>>       CU_ASSERT(odp_time_cmp(t2, sum) == 0);
>>   }
>>
>> @@ -235,7 +262,7 @@ void time_test_odp_to_u64(void)
>>
>>       CU_ASSERT(val2 > val1);
>>
>> -    val1 = odp_time_to_u64(ODP_TIME_NULL);
>> +    val1 = odp_time_to_u64(ODP_TIME_NULL_VAL);
>>       CU_ASSERT(val1 == 0);
>>   }
>>
>>
>
Ivan Khoronzhuk Nov. 23, 2015, 5:25 p.m. UTC | #3
On 23.11.15 17:17, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> The two API spec changes (monotonic and wall time) should be combined into one patch that changes only the API spec.
It allows to test and see two significant changes separately.
But if you wish I will try to combine them.

>  Also terms "monotonic" and "wall time" should be replaced with tight specification, like
>
> "Local time is initialized to zero during ODP startup and will not wrap around in at least xxx years".
Ok, will replace terms on descriptions.

>
> Test and other code changes which take advantage on the changed spec can then follow in another patch.
It can but tests are working incorrectly after that change, with bugs inside.
So I will leave it in one patch.

>
> Why intervals and odp_time_local_val() / odp_time_val_to_ns() are needed.
>  For example, what is the difference of timestamp after xxx years and interval from 0 to xxx years?
The wrap is not concern here. They needed to avoid redundant extractions while odp_time_local() for simple cases.
Will try to remove it as it simplification for implementation and accuracy and leaved from legacy thoughts.

>  Time API should be able to handle both equally if it is defined to start from 0 and never wrap.
>
> -Petri
>
>
>> -----Original Message-----
>> From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of EXT
>> Ivan Khoronzhuk
>> Sent: Thursday, November 12, 2015 7:45 PM
>> To: lng-odp@lists.linaro.org
>> Subject: [lng-odp] [lng] [API-NEXT PATCH v2 7/7] api: time: make local
>> time to be wall time
>>
>> It's more convenient the local time to be a wall time. It's allows
>> to measure time beginning from start of the thread. This allows to use
>> local time in similar manner as it's supposed to be used with global
>> time and the 64-bit timer is enough to guarantee it.
>> Correct validation test to check new time API.
>>
>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> ---
>>   example/generator/odp_generator.c                  |  2 +-
>>   include/odp/api/time.h                             | 30 ++++++++--
>>   .../linux-generic/include/odp/plat/time_types.h    |  4 +-
>>   platform/linux-generic/include/odp_internal.h      |  2 +
>>   platform/linux-generic/odp_schedule.c              |  2 +-
>>   platform/linux-generic/odp_time.c                  | 58 ++++++++++++++++-
>> --
>>   test/performance/odp_pktio_perf.c                  | 24 ++++----
>>   test/validation/pktio/pktio.c                      |  4 +-
>>   test/validation/scheduler/scheduler.c              |  2 +-
>>   test/validation/time/time.c                        | 67 +++++++++++++++--
>> -----
>>   10 files changed, 143 insertions(+), 52 deletions(-)
>>
>> diff --git a/example/generator/odp_generator.c
>> b/example/generator/odp_generator.c
>> index 2de530d..ddae7c0 100644
>> --- a/example/generator/odp_generator.c
>> +++ b/example/generator/odp_generator.c
>> @@ -594,7 +594,7 @@ static void print_global_stats(int num_workers)
>>   	while (odp_thrmask_worker(&thrd_mask) < num_workers)
>>   		continue;
>>
>> -	wait = odp_time_local_from_ns(verbose_interval *
>> ODP_TIME_SEC_IN_NS);
>> +	wait = odp_time_local_val(verbose_interval * ODP_TIME_SEC_IN_NS);
>>   	next = odp_time_sum(odp_time_local(), wait);
>>
>>   	while (odp_thrmask_worker(&thrd_mask) == num_workers) {
>> diff --git a/include/odp/api/time.h b/include/odp/api/time.h
>> index 3228879..9a5916b 100644
>> --- a/include/odp/api/time.h
>> +++ b/include/odp/api/time.h
>> @@ -37,15 +37,16 @@ extern "C" {
>>    */
>>
>>   /**
>> - * @def ODP_TIME_NULL
>> - * Zero time stamp
>> + * @def ODP_TIME_NULL_VAL
>> + * Zero time interval
>>    */
>>
>>   /**
>>    * Current local time
>>    *
>>    * Returns current local time stamp value. The local time source provides
>> high
>> - * resolution time and is monotonic.
>> + * resolution time and is monotonic. The local time is wall time that
>> means it's
>> + * local for each thread.
>>    *
>>    * @return Local time stamp.
>>    */
>> @@ -57,7 +58,9 @@ odp_time_t odp_time_local(void);
>>    * @param t2    Second time stamp
>>    * @param t1    First time stamp
>>    *
>> - * @return Difference of time stamps
>> + * @return Difference of time stamps ot intervals. Diff of timestamp and
>> + * interval results in timestamp.
>> + *
>>    */
>>   odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>
>> @@ -68,6 +71,9 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>    * @param t2    Time stamp
>>    *
>>    * @return Sum of time stamps
>> + *
>> + * @note Sum of two timestamp shouldn't be used, only timestamp and
>> interval or
>> + * two intervals. Sum of timestamp and interval results in timestamp.
>>    */
>>   odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
>>
>> @@ -90,12 +96,28 @@ uint64_t odp_time_to_ns(odp_time_t time);
>>   odp_time_t odp_time_local_from_ns(uint64_t ns);
>>
>>   /**
>> + * Convert nanoseconds to interval of local time
>> + *
>> + * @param ns	Time in nanoseconds
>> + */
>> +odp_time_t odp_time_local_val(uint64_t ns);
>> +
>> +/**
>> + * Convert time interval to nanoseconds
>> + *
>> + * @param val	Time interval
>> + */
>> +uint64_t odp_time_val_to_ns(odp_time_t val);
>> +
>> +/**
>>    * Compare two times
>>    *
>>    * @param t2    Second time
>>    * @param t1    First time
>>    *
>>    * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1
>> + *
>> + * @note Compare two timestamps or two intervals
>>    */
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1);
>>
>> diff --git a/platform/linux-generic/include/odp/plat/time_types.h
>> b/platform/linux-generic/include/odp/plat/time_types.h
>> index e5765ec..ccf6580 100644
>> --- a/platform/linux-generic/include/odp/plat/time_types.h
>> +++ b/platform/linux-generic/include/odp/plat/time_types.h
>> @@ -23,9 +23,9 @@ extern "C" {
>>
>>   typedef struct timespec odp_time_t;
>>
>> -odp_time_t odp_time_null(void);
>> +odp_time_t odp_time_null_val(void);
>>
>> -#define ODP_TIME_NULL	odp_time_null()
>> +#define ODP_TIME_NULL_VAL	odp_time_null_val()
>>
>>   /**
>>    * @}
>> diff --git a/platform/linux-generic/include/odp_internal.h
>> b/platform/linux-generic/include/odp_internal.h
>> index 14ba159..baff135 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_local_init(void);
>> +
>>   void _odp_flush_caches(void);
>>
>>   #ifdef __cplusplus
>> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
>> generic/odp_schedule.c
>> index 3017876..6a3440c 100644
>> --- a/platform/linux-generic/odp_schedule.c
>> +++ b/platform/linux-generic/odp_schedule.c
>> @@ -603,7 +603,7 @@ static int schedule_loop(odp_queue_t *out_queue,
>> uint64_t wait,
>>   			break;
>>
>>   		if (first) {
>> -			wtime = odp_time_local_from_ns(wait);
>> +			wtime = odp_time_local_val(wait);
>>   			next = odp_time_sum(odp_time_local(), wtime);
>>   			first = 0;
>>   			continue;
>> diff --git a/platform/linux-generic/odp_time.c b/platform/linux-
>> generic/odp_time.c
>> index 73b2dcb..c82f974 100644
>> --- a/platform/linux-generic/odp_time.c
>> +++ b/platform/linux-generic/odp_time.c
>> @@ -11,6 +11,30 @@
>>   #include <odp/hints.h>
>>   #include <odp_debug_internal.h>
>>
>> +static __thread uint64_t start_local_ns;
>> +
>> +static inline
>> +odp_time_t _odp_time_local_val(uint64_t ns)
>> +{
>> +	struct timespec val;
>> +
>> +	val.tv_sec = ns / ODP_TIME_SEC_IN_NS;
>> +	val.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
>> +
>> +	return val;
>> +}
>> +
>> +static inline
>> +uint64_t _odp_time_val_to_ns(odp_time_t val)
>> +{
>> +	uint64_t ns;
>> +
>> +	ns = val.tv_sec * ODP_TIME_SEC_IN_NS;
>> +	ns += val.tv_nsec;
>> +
>> +	return ns;
>> +}
>> +
>>   odp_time_t odp_time_local(void)
>>   {
>>   	int ret;
>> @@ -38,24 +62,30 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
>>   	return time;
>>   }
>>
>> +uint64_t odp_time_val_to_ns(odp_time_t val)
>> +{
>> +	return _odp_time_val_to_ns(val);
>> +}
>> +
>>   uint64_t odp_time_to_ns(odp_time_t time)
>>   {
>>   	uint64_t ns;
>>
>> -	ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
>> -	ns += time.tv_nsec;
>> +	ns = _odp_time_val_to_ns(time);
>> +	ns -= start_local_ns;
>>
>>   	return ns;
>>   }
>>
>>   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;
>> +	ns += start_local_ns;
>> +	return _odp_time_local_val(ns);
>> +}
>>
>> -	return time;
>> +odp_time_t odp_time_local_val(uint64_t ns)
>> +{
>> +	return _odp_time_local_val(ns);
>>   }
>>
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1)
>> @@ -96,11 +126,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 _odp_time_val_to_ns(time) / resolution;
>>   }
>>
>> -odp_time_t odp_time_null(void)
>> +odp_time_t odp_time_null_val(void)
>>   {
>>   	return (struct timespec) {0, 0};
>>   }
>>
>> +int odp_time_local_init(void)
>> +{
>> +	int ret;
>> +	struct timespec time;
>> +
>> +	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
>> +	start_local_ns = ret ? 0 : _odp_time_val_to_ns(time);
>> +
>> +	return ret;
>> +}
>> diff --git a/test/performance/odp_pktio_perf.c
>> b/test/performance/odp_pktio_perf.c
>> index 3d37ae1..e1f65e4 100644
>> --- a/test/performance/odp_pktio_perf.c
>> +++ b/test/performance/odp_pktio_perf.c
>> @@ -310,7 +310,7 @@ static void *run_thread_tx(void *arg)
>>   	uint32_t batch_len;
>>   	int unsent_pkts = 0;
>>   	odp_event_t  tx_event[BATCH_LEN_MAX];
>> -	odp_time_t idle_start = ODP_TIME_NULL;
>> +	odp_time_t idle_start = ODP_TIME_NULL_VAL;
>>
>>   	thread_args_t *targs = arg;
>>
>> @@ -328,10 +328,10 @@ static void *run_thread_tx(void *arg)
>>   	if (outq == ODP_QUEUE_INVALID)
>>   		LOG_ABORT("Failed to get output queue for thread %d\n",
>> thr_id);
>>
>> -	burst_gap = odp_time_local_from_ns(
>> +	burst_gap = odp_time_local_val(
>>   			ODP_TIME_SEC_IN_NS / (targs->pps / targs->batch_len));
>>   	send_duration =
>> -		odp_time_local_from_ns(targs->duration * ODP_TIME_SEC_IN_NS);
>> +		odp_time_local_val(targs->duration * ODP_TIME_SEC_IN_NS);
>>
>>   	odp_barrier_wait(&globals->tx_barrier);
>>
>> @@ -343,18 +343,18 @@ static void *run_thread_tx(void *arg)
>>
>>   		if (odp_time_cmp(burst_gap_end, cur_time) > 0) {
>>   			cur_time = odp_time_local();
>> -			if (!odp_time_cmp(idle_start, ODP_TIME_NULL))
>> +			if (!odp_time_cmp(idle_start, ODP_TIME_NULL_VAL))
>>   				idle_start = cur_time;
>>   			continue;
>>   		}
>>
>> -		if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) {
>> +		if (odp_time_cmp(idle_start, ODP_TIME_NULL_VAL) > 0) {
>>   			odp_time_t diff = odp_time_diff(cur_time, idle_start);
>>
>>   			stats->s.idle_ticks =
>>   				odp_time_sum(diff, stats->s.idle_ticks);
>>
>> -			idle_start = ODP_TIME_NULL;
>> +			idle_start = ODP_TIME_NULL_VAL;
>>   		}
>>
>>   		burst_gap_end = odp_time_sum(burst_gap_end, burst_gap);
>> @@ -375,7 +375,7 @@ static void *run_thread_tx(void *arg)
>>   	       " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
>>   	       thr_id, stats->s.tx_cnt,
>>   	       stats->s.enq_failures, stats->s.alloc_failures,
>> -	       odp_time_to_ns(stats->s.idle_ticks) /
>> +	       odp_time_val_to_ns(stats->s.idle_ticks) /
>>   	       (uint64_t)ODP_TIME_MSEC_IN_NS);
>>
>>   	return NULL;
>> @@ -595,13 +595,13 @@ static int setup_txrx_masks(odp_cpumask_t
>> *thd_mask_tx,
>>    */
>>   static void busy_loop_ns(uint64_t wait_ns)
>>   {
>> -	odp_time_t diff;
>> -	odp_time_t start_time = odp_time_local();
>> -	odp_time_t wait = odp_time_local_from_ns(wait_ns);
>> +	odp_time_t wait = odp_time_local_val(wait_ns);
>> +	odp_time_t cur = odp_time_local();
>> +	odp_time_t end_time = odp_time_sum(cur, wait);
>>
>>   	do {
>> -		diff = odp_time_diff(odp_time_local(), start_time);
>> -	} while (odp_time_cmp(wait, diff) > 0);
>> +		cur = odp_time_local();
>> +	} while (odp_time_cmp(end_time, cur) > 0);
>>   }
>>
>>   /*
>> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
>> index aee3a7d..6d7e954 100644
>> --- a/test/validation/pktio/pktio.c
>> +++ b/test/validation/pktio/pktio.c
>> @@ -339,7 +339,7 @@ static odp_event_t queue_deq_wait_time(odp_queue_t
>> queue, uint64_t ns)
>>   	odp_time_t wait, end;
>>   	odp_event_t ev;
>>
>> -	wait = odp_time_local_from_ns(ns);
>> +	wait = odp_time_local_val(ns);
>>   	end = odp_time_sum(odp_time_local(), wait);
>>   	do {
>>   		ev = odp_queue_deq(queue);
>> @@ -359,7 +359,7 @@ static odp_packet_t wait_for_packet(pktio_info_t
>> *pktio_rx,
>>   	uint64_t wait;
>>
>>   	wait = odp_schedule_wait_time(ns);
>> -	wait_time = odp_time_local_from_ns(ns);
>> +	wait_time = odp_time_local_val(ns);
>>   	end = odp_time_sum(odp_time_local(), wait_time);
>>   	do {
>>   		pkt = ODP_PACKET_INVALID;
>> diff --git a/test/validation/scheduler/scheduler.c
>> b/test/validation/scheduler/scheduler.c
>> index a562a8a..58f93e0 100644
>> --- a/test/validation/scheduler/scheduler.c
>> +++ b/test/validation/scheduler/scheduler.c
>> @@ -718,7 +718,7 @@ static void *schedule_common_(void *arg)
>>   			CU_ASSERT(from != ODP_QUEUE_INVALID);
>>   			if (locked) {
>>   				int cnt;
>> -				odp_time_t time = ODP_TIME_NULL;
>> +				odp_time_t time = ODP_TIME_NULL_VAL;
>>   				/* Do some work here to keep the thread busy */
>>   				for (cnt = 0; cnt < 1000; cnt++)
>>   					time = odp_time_sum(time,
>> diff --git a/test/validation/time/time.c b/test/validation/time/time.c
>> index 8f5dfe6..4386c34 100644
>> --- a/test/validation/time/time.c
>> +++ b/test/validation/time/time.c
>> @@ -18,6 +18,7 @@ void time_test_odp_conversion(void)
>>   	odp_time_t time;
>>   	uint64_t upper_limit, lower_limit;
>>
>> +	/* test timestamp conversions */
>>   	ns1 = 100;
>>   	time = odp_time_local_from_ns(ns1);
>>
>> @@ -34,8 +35,18 @@ void time_test_odp_conversion(void)
>>
>>   	ns2 = odp_time_to_ns(time);
>>
>> -	/* need to check within arithmetic tolerance that the same
>> -	 * value in ns is returned after conversions */
>> +	/*
>> +	 * need to check within arithmetic tolerance that the same
>> +	 * value in ns is returned after conversions
>> +	 */
>> +	upper_limit = ns1 + TOLERANCE;
>> +	lower_limit = ns1 - TOLERANCE;
>> +	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> +
>> +	/* test time vals conversions */
>> +	time = odp_time_local_val(ns1);
>> +	ns2 = odp_time_val_to_ns(time);
>> +
>>   	upper_limit = ns1 + TOLERANCE;
>>   	lower_limit = ns1 - TOLERANCE;
>>   	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> @@ -75,6 +86,7 @@ void time_test_odp_cmp(void)
>>   	volatile int count = 0;
>>   	odp_time_t t1, t2, t3;
>>
>> +	/* test compare of timestamps */
>>   	t1 = odp_time_local();
>>
>>   	while (count < BUSY_LOOP_CNT) {
>> @@ -105,8 +117,23 @@ void time_test_odp_cmp(void)
>>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>   	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>>
>> -	t1 = odp_time_local_from_ns(0);
>> -	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0);
>> +	t1 = odp_time_local_val(0);
>> +	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL_VAL) == 0);
>> +
>> +	/* test compare of time intervals */
>> +	t1 = odp_time_local_val(15);
>> +	t2 = odp_time_local_val(23);
>> +	t3 = odp_time_local_val(51);
>> +
>> +	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t2) > 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t1) > 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>> +	CU_ASSERT(odp_time_cmp(t2, t3) < 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t3) < 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t1) == 0);
>> +	CU_ASSERT(odp_time_cmp(t2, t2) == 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t3) == 0);
>>   }
>>
>>   /* check that a time difference gives a reasonable result */
>> @@ -129,12 +156,12 @@ void time_test_odp_diff(void)
>>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>
>>   	ns1 = odp_time_to_ns(t1);
>>   	ns2 = odp_time_to_ns(t2);
>>   	ns = ns2 - ns1;
>> -	nsdiff = odp_time_to_ns(diff);
>> +	nsdiff = odp_time_val_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>> @@ -142,11 +169,11 @@ void time_test_odp_diff(void)
>>
>>   	/* test timestamp and interval diff */
>>   	ns1 = 54;
>> -	t1 = odp_time_local_from_ns(ns1);
>> +	t1 = odp_time_local_val(ns1);
>>   	ns = ns2 - ns1;
>>
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>   	nsdiff = odp_time_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>> @@ -157,10 +184,10 @@ void time_test_odp_diff(void)
>>   	ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS;
>>   	ns = ns2 - ns1;
>>
>> -	t2 = odp_time_local_from_ns(ns2);
>> +	t2 = odp_time_local_val(ns2);
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> -	nsdiff = odp_time_to_ns(diff);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>> +	nsdiff = odp_time_val_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>> @@ -168,9 +195,9 @@ void time_test_odp_diff(void)
>>
>>   	/* same time has to diff to 0 */
>>   	diff = odp_time_diff(t2, t2);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) == 0);
>>
>> -	diff = odp_time_diff(t2, ODP_TIME_NULL);
>> +	diff = odp_time_diff(t2, ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(odp_time_cmp(t2, diff) == 0);
>>   }
>>
>> @@ -184,12 +211,12 @@ void time_test_odp_sum(void)
>>   	/* sum timestamp and interval */
>>   	t1 = odp_time_local();
>>   	ns2 = 103;
>> -	t2 = odp_time_local_from_ns(ns2);
>> +	t2 = odp_time_local_val(ns2);
>>   	ns1 = odp_time_to_ns(t1);
>>   	ns = ns1 + ns2;
>>
>>   	sum = odp_time_sum(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>>   	nssum = odp_time_to_ns(sum);
>>
>>   	upper_limit = ns + TOLERANCE;
>> @@ -198,19 +225,19 @@ void time_test_odp_sum(void)
>>
>>   	/* sum intervals */
>>   	ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS;
>> -	t1 = odp_time_local_from_ns(ns1);
>> +	t1 = odp_time_local_val(ns1);
>>   	ns = ns1 + ns2;
>>
>>   	sum = odp_time_sum(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> -	nssum = odp_time_to_ns(sum);
>> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>> +	nssum = odp_time_val_to_ns(sum);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>>   	CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit));
>>
>>   	/* test on 0 */
>> -	sum = odp_time_sum(t2, ODP_TIME_NULL);
>> +	sum = odp_time_sum(t2, ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(odp_time_cmp(t2, sum) == 0);
>>   }
>>
>> @@ -235,7 +262,7 @@ void time_test_odp_to_u64(void)
>>
>>   	CU_ASSERT(val2 > val1);
>>
>> -	val1 = odp_time_to_u64(ODP_TIME_NULL);
>> +	val1 = odp_time_to_u64(ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(val1 == 0);
>>   }
>>
>> --
>> 1.9.1
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
Ivan Khoronzhuk Nov. 23, 2015, 9:24 p.m. UTC | #4
Petri,

v3 has been sent.

On 23.11.15 17:17, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> The two API spec changes (monotonic and wall time) should be combined into one patch that changes only the API spec. Also terms "monotonic" and "wall time" should be replaced with tight specification, like
>
> "Local time is initialized to zero during ODP startup and will not wrap around in at least xxx years".
>
> Test and other code changes which take advantage on the changed spec can then follow in another patch.
>
> Why intervals and odp_time_local_val() / odp_time_val_to_ns() are needed. For example, what is the difference of timestamp after xxx years and interval from 0 to xxx years? Time API should be able to handle both equally if it is defined to start from 0 and never wrap.
>
> -Petri
>
>
>> -----Original Message-----
>> From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of EXT
>> Ivan Khoronzhuk
>> Sent: Thursday, November 12, 2015 7:45 PM
>> To: lng-odp@lists.linaro.org
>> Subject: [lng-odp] [lng] [API-NEXT PATCH v2 7/7] api: time: make local
>> time to be wall time
>>
>> It's more convenient the local time to be a wall time. It's allows
>> to measure time beginning from start of the thread. This allows to use
>> local time in similar manner as it's supposed to be used with global
>> time and the 64-bit timer is enough to guarantee it.
>> Correct validation test to check new time API.
>>
>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> ---
>>   example/generator/odp_generator.c                  |  2 +-
>>   include/odp/api/time.h                             | 30 ++++++++--
>>   .../linux-generic/include/odp/plat/time_types.h    |  4 +-
>>   platform/linux-generic/include/odp_internal.h      |  2 +
>>   platform/linux-generic/odp_schedule.c              |  2 +-
>>   platform/linux-generic/odp_time.c                  | 58 ++++++++++++++++-
>> --
>>   test/performance/odp_pktio_perf.c                  | 24 ++++----
>>   test/validation/pktio/pktio.c                      |  4 +-
>>   test/validation/scheduler/scheduler.c              |  2 +-
>>   test/validation/time/time.c                        | 67 +++++++++++++++--
>> -----
>>   10 files changed, 143 insertions(+), 52 deletions(-)
>>
>> diff --git a/example/generator/odp_generator.c
>> b/example/generator/odp_generator.c
>> index 2de530d..ddae7c0 100644
>> --- a/example/generator/odp_generator.c
>> +++ b/example/generator/odp_generator.c
>> @@ -594,7 +594,7 @@ static void print_global_stats(int num_workers)
>>   	while (odp_thrmask_worker(&thrd_mask) < num_workers)
>>   		continue;
>>
>> -	wait = odp_time_local_from_ns(verbose_interval *
>> ODP_TIME_SEC_IN_NS);
>> +	wait = odp_time_local_val(verbose_interval * ODP_TIME_SEC_IN_NS);
>>   	next = odp_time_sum(odp_time_local(), wait);
>>
>>   	while (odp_thrmask_worker(&thrd_mask) == num_workers) {
>> diff --git a/include/odp/api/time.h b/include/odp/api/time.h
>> index 3228879..9a5916b 100644
>> --- a/include/odp/api/time.h
>> +++ b/include/odp/api/time.h
>> @@ -37,15 +37,16 @@ extern "C" {
>>    */
>>
>>   /**
>> - * @def ODP_TIME_NULL
>> - * Zero time stamp
>> + * @def ODP_TIME_NULL_VAL
>> + * Zero time interval
>>    */
>>
>>   /**
>>    * Current local time
>>    *
>>    * Returns current local time stamp value. The local time source provides
>> high
>> - * resolution time and is monotonic.
>> + * resolution time and is monotonic. The local time is wall time that
>> means it's
>> + * local for each thread.
>>    *
>>    * @return Local time stamp.
>>    */
>> @@ -57,7 +58,9 @@ odp_time_t odp_time_local(void);
>>    * @param t2    Second time stamp
>>    * @param t1    First time stamp
>>    *
>> - * @return Difference of time stamps
>> + * @return Difference of time stamps ot intervals. Diff of timestamp and
>> + * interval results in timestamp.
>> + *
>>    */
>>   odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>
>> @@ -68,6 +71,9 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
>>    * @param t2    Time stamp
>>    *
>>    * @return Sum of time stamps
>> + *
>> + * @note Sum of two timestamp shouldn't be used, only timestamp and
>> interval or
>> + * two intervals. Sum of timestamp and interval results in timestamp.
>>    */
>>   odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
>>
>> @@ -90,12 +96,28 @@ uint64_t odp_time_to_ns(odp_time_t time);
>>   odp_time_t odp_time_local_from_ns(uint64_t ns);
>>
>>   /**
>> + * Convert nanoseconds to interval of local time
>> + *
>> + * @param ns	Time in nanoseconds
>> + */
>> +odp_time_t odp_time_local_val(uint64_t ns);
>> +
>> +/**
>> + * Convert time interval to nanoseconds
>> + *
>> + * @param val	Time interval
>> + */
>> +uint64_t odp_time_val_to_ns(odp_time_t val);
>> +
>> +/**
>>    * Compare two times
>>    *
>>    * @param t2    Second time
>>    * @param t1    First time
>>    *
>>    * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1
>> + *
>> + * @note Compare two timestamps or two intervals
>>    */
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1);
>>
>> diff --git a/platform/linux-generic/include/odp/plat/time_types.h
>> b/platform/linux-generic/include/odp/plat/time_types.h
>> index e5765ec..ccf6580 100644
>> --- a/platform/linux-generic/include/odp/plat/time_types.h
>> +++ b/platform/linux-generic/include/odp/plat/time_types.h
>> @@ -23,9 +23,9 @@ extern "C" {
>>
>>   typedef struct timespec odp_time_t;
>>
>> -odp_time_t odp_time_null(void);
>> +odp_time_t odp_time_null_val(void);
>>
>> -#define ODP_TIME_NULL	odp_time_null()
>> +#define ODP_TIME_NULL_VAL	odp_time_null_val()
>>
>>   /**
>>    * @}
>> diff --git a/platform/linux-generic/include/odp_internal.h
>> b/platform/linux-generic/include/odp_internal.h
>> index 14ba159..baff135 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_local_init(void);
>> +
>>   void _odp_flush_caches(void);
>>
>>   #ifdef __cplusplus
>> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
>> generic/odp_schedule.c
>> index 3017876..6a3440c 100644
>> --- a/platform/linux-generic/odp_schedule.c
>> +++ b/platform/linux-generic/odp_schedule.c
>> @@ -603,7 +603,7 @@ static int schedule_loop(odp_queue_t *out_queue,
>> uint64_t wait,
>>   			break;
>>
>>   		if (first) {
>> -			wtime = odp_time_local_from_ns(wait);
>> +			wtime = odp_time_local_val(wait);
>>   			next = odp_time_sum(odp_time_local(), wtime);
>>   			first = 0;
>>   			continue;
>> diff --git a/platform/linux-generic/odp_time.c b/platform/linux-
>> generic/odp_time.c
>> index 73b2dcb..c82f974 100644
>> --- a/platform/linux-generic/odp_time.c
>> +++ b/platform/linux-generic/odp_time.c
>> @@ -11,6 +11,30 @@
>>   #include <odp/hints.h>
>>   #include <odp_debug_internal.h>
>>
>> +static __thread uint64_t start_local_ns;
>> +
>> +static inline
>> +odp_time_t _odp_time_local_val(uint64_t ns)
>> +{
>> +	struct timespec val;
>> +
>> +	val.tv_sec = ns / ODP_TIME_SEC_IN_NS;
>> +	val.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
>> +
>> +	return val;
>> +}
>> +
>> +static inline
>> +uint64_t _odp_time_val_to_ns(odp_time_t val)
>> +{
>> +	uint64_t ns;
>> +
>> +	ns = val.tv_sec * ODP_TIME_SEC_IN_NS;
>> +	ns += val.tv_nsec;
>> +
>> +	return ns;
>> +}
>> +
>>   odp_time_t odp_time_local(void)
>>   {
>>   	int ret;
>> @@ -38,24 +62,30 @@ odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
>>   	return time;
>>   }
>>
>> +uint64_t odp_time_val_to_ns(odp_time_t val)
>> +{
>> +	return _odp_time_val_to_ns(val);
>> +}
>> +
>>   uint64_t odp_time_to_ns(odp_time_t time)
>>   {
>>   	uint64_t ns;
>>
>> -	ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
>> -	ns += time.tv_nsec;
>> +	ns = _odp_time_val_to_ns(time);
>> +	ns -= start_local_ns;
>>
>>   	return ns;
>>   }
>>
>>   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;
>> +	ns += start_local_ns;
>> +	return _odp_time_local_val(ns);
>> +}
>>
>> -	return time;
>> +odp_time_t odp_time_local_val(uint64_t ns)
>> +{
>> +	return _odp_time_local_val(ns);
>>   }
>>
>>   int odp_time_cmp(odp_time_t t2, odp_time_t t1)
>> @@ -96,11 +126,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 _odp_time_val_to_ns(time) / resolution;
>>   }
>>
>> -odp_time_t odp_time_null(void)
>> +odp_time_t odp_time_null_val(void)
>>   {
>>   	return (struct timespec) {0, 0};
>>   }
>>
>> +int odp_time_local_init(void)
>> +{
>> +	int ret;
>> +	struct timespec time;
>> +
>> +	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
>> +	start_local_ns = ret ? 0 : _odp_time_val_to_ns(time);
>> +
>> +	return ret;
>> +}
>> diff --git a/test/performance/odp_pktio_perf.c
>> b/test/performance/odp_pktio_perf.c
>> index 3d37ae1..e1f65e4 100644
>> --- a/test/performance/odp_pktio_perf.c
>> +++ b/test/performance/odp_pktio_perf.c
>> @@ -310,7 +310,7 @@ static void *run_thread_tx(void *arg)
>>   	uint32_t batch_len;
>>   	int unsent_pkts = 0;
>>   	odp_event_t  tx_event[BATCH_LEN_MAX];
>> -	odp_time_t idle_start = ODP_TIME_NULL;
>> +	odp_time_t idle_start = ODP_TIME_NULL_VAL;
>>
>>   	thread_args_t *targs = arg;
>>
>> @@ -328,10 +328,10 @@ static void *run_thread_tx(void *arg)
>>   	if (outq == ODP_QUEUE_INVALID)
>>   		LOG_ABORT("Failed to get output queue for thread %d\n",
>> thr_id);
>>
>> -	burst_gap = odp_time_local_from_ns(
>> +	burst_gap = odp_time_local_val(
>>   			ODP_TIME_SEC_IN_NS / (targs->pps / targs->batch_len));
>>   	send_duration =
>> -		odp_time_local_from_ns(targs->duration * ODP_TIME_SEC_IN_NS);
>> +		odp_time_local_val(targs->duration * ODP_TIME_SEC_IN_NS);
>>
>>   	odp_barrier_wait(&globals->tx_barrier);
>>
>> @@ -343,18 +343,18 @@ static void *run_thread_tx(void *arg)
>>
>>   		if (odp_time_cmp(burst_gap_end, cur_time) > 0) {
>>   			cur_time = odp_time_local();
>> -			if (!odp_time_cmp(idle_start, ODP_TIME_NULL))
>> +			if (!odp_time_cmp(idle_start, ODP_TIME_NULL_VAL))
>>   				idle_start = cur_time;
>>   			continue;
>>   		}
>>
>> -		if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) {
>> +		if (odp_time_cmp(idle_start, ODP_TIME_NULL_VAL) > 0) {
>>   			odp_time_t diff = odp_time_diff(cur_time, idle_start);
>>
>>   			stats->s.idle_ticks =
>>   				odp_time_sum(diff, stats->s.idle_ticks);
>>
>> -			idle_start = ODP_TIME_NULL;
>> +			idle_start = ODP_TIME_NULL_VAL;
>>   		}
>>
>>   		burst_gap_end = odp_time_sum(burst_gap_end, burst_gap);
>> @@ -375,7 +375,7 @@ static void *run_thread_tx(void *arg)
>>   	       " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
>>   	       thr_id, stats->s.tx_cnt,
>>   	       stats->s.enq_failures, stats->s.alloc_failures,
>> -	       odp_time_to_ns(stats->s.idle_ticks) /
>> +	       odp_time_val_to_ns(stats->s.idle_ticks) /
>>   	       (uint64_t)ODP_TIME_MSEC_IN_NS);
>>
>>   	return NULL;
>> @@ -595,13 +595,13 @@ static int setup_txrx_masks(odp_cpumask_t
>> *thd_mask_tx,
>>    */
>>   static void busy_loop_ns(uint64_t wait_ns)
>>   {
>> -	odp_time_t diff;
>> -	odp_time_t start_time = odp_time_local();
>> -	odp_time_t wait = odp_time_local_from_ns(wait_ns);
>> +	odp_time_t wait = odp_time_local_val(wait_ns);
>> +	odp_time_t cur = odp_time_local();
>> +	odp_time_t end_time = odp_time_sum(cur, wait);
>>
>>   	do {
>> -		diff = odp_time_diff(odp_time_local(), start_time);
>> -	} while (odp_time_cmp(wait, diff) > 0);
>> +		cur = odp_time_local();
>> +	} while (odp_time_cmp(end_time, cur) > 0);
>>   }
>>
>>   /*
>> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
>> index aee3a7d..6d7e954 100644
>> --- a/test/validation/pktio/pktio.c
>> +++ b/test/validation/pktio/pktio.c
>> @@ -339,7 +339,7 @@ static odp_event_t queue_deq_wait_time(odp_queue_t
>> queue, uint64_t ns)
>>   	odp_time_t wait, end;
>>   	odp_event_t ev;
>>
>> -	wait = odp_time_local_from_ns(ns);
>> +	wait = odp_time_local_val(ns);
>>   	end = odp_time_sum(odp_time_local(), wait);
>>   	do {
>>   		ev = odp_queue_deq(queue);
>> @@ -359,7 +359,7 @@ static odp_packet_t wait_for_packet(pktio_info_t
>> *pktio_rx,
>>   	uint64_t wait;
>>
>>   	wait = odp_schedule_wait_time(ns);
>> -	wait_time = odp_time_local_from_ns(ns);
>> +	wait_time = odp_time_local_val(ns);
>>   	end = odp_time_sum(odp_time_local(), wait_time);
>>   	do {
>>   		pkt = ODP_PACKET_INVALID;
>> diff --git a/test/validation/scheduler/scheduler.c
>> b/test/validation/scheduler/scheduler.c
>> index a562a8a..58f93e0 100644
>> --- a/test/validation/scheduler/scheduler.c
>> +++ b/test/validation/scheduler/scheduler.c
>> @@ -718,7 +718,7 @@ static void *schedule_common_(void *arg)
>>   			CU_ASSERT(from != ODP_QUEUE_INVALID);
>>   			if (locked) {
>>   				int cnt;
>> -				odp_time_t time = ODP_TIME_NULL;
>> +				odp_time_t time = ODP_TIME_NULL_VAL;
>>   				/* Do some work here to keep the thread busy */
>>   				for (cnt = 0; cnt < 1000; cnt++)
>>   					time = odp_time_sum(time,
>> diff --git a/test/validation/time/time.c b/test/validation/time/time.c
>> index 8f5dfe6..4386c34 100644
>> --- a/test/validation/time/time.c
>> +++ b/test/validation/time/time.c
>> @@ -18,6 +18,7 @@ void time_test_odp_conversion(void)
>>   	odp_time_t time;
>>   	uint64_t upper_limit, lower_limit;
>>
>> +	/* test timestamp conversions */
>>   	ns1 = 100;
>>   	time = odp_time_local_from_ns(ns1);
>>
>> @@ -34,8 +35,18 @@ void time_test_odp_conversion(void)
>>
>>   	ns2 = odp_time_to_ns(time);
>>
>> -	/* need to check within arithmetic tolerance that the same
>> -	 * value in ns is returned after conversions */
>> +	/*
>> +	 * need to check within arithmetic tolerance that the same
>> +	 * value in ns is returned after conversions
>> +	 */
>> +	upper_limit = ns1 + TOLERANCE;
>> +	lower_limit = ns1 - TOLERANCE;
>> +	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> +
>> +	/* test time vals conversions */
>> +	time = odp_time_local_val(ns1);
>> +	ns2 = odp_time_val_to_ns(time);
>> +
>>   	upper_limit = ns1 + TOLERANCE;
>>   	lower_limit = ns1 - TOLERANCE;
>>   	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
>> @@ -75,6 +86,7 @@ void time_test_odp_cmp(void)
>>   	volatile int count = 0;
>>   	odp_time_t t1, t2, t3;
>>
>> +	/* test compare of timestamps */
>>   	t1 = odp_time_local();
>>
>>   	while (count < BUSY_LOOP_CNT) {
>> @@ -105,8 +117,23 @@ void time_test_odp_cmp(void)
>>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>   	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>>
>> -	t1 = odp_time_local_from_ns(0);
>> -	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0);
>> +	t1 = odp_time_local_val(0);
>> +	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL_VAL) == 0);
>> +
>> +	/* test compare of time intervals */
>> +	t1 = odp_time_local_val(15);
>> +	t2 = odp_time_local_val(23);
>> +	t3 = odp_time_local_val(51);
>> +
>> +	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t2) > 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t1) > 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
>> +	CU_ASSERT(odp_time_cmp(t2, t3) < 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t3) < 0);
>> +	CU_ASSERT(odp_time_cmp(t1, t1) == 0);
>> +	CU_ASSERT(odp_time_cmp(t2, t2) == 0);
>> +	CU_ASSERT(odp_time_cmp(t3, t3) == 0);
>>   }
>>
>>   /* check that a time difference gives a reasonable result */
>> @@ -129,12 +156,12 @@ void time_test_odp_diff(void)
>>   	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
>>
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>
>>   	ns1 = odp_time_to_ns(t1);
>>   	ns2 = odp_time_to_ns(t2);
>>   	ns = ns2 - ns1;
>> -	nsdiff = odp_time_to_ns(diff);
>> +	nsdiff = odp_time_val_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>> @@ -142,11 +169,11 @@ void time_test_odp_diff(void)
>>
>>   	/* test timestamp and interval diff */
>>   	ns1 = 54;
>> -	t1 = odp_time_local_from_ns(ns1);
>> +	t1 = odp_time_local_val(ns1);
>>   	ns = ns2 - ns1;
>>
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>>   	nsdiff = odp_time_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>> @@ -157,10 +184,10 @@ void time_test_odp_diff(void)
>>   	ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS;
>>   	ns = ns2 - ns1;
>>
>> -	t2 = odp_time_local_from_ns(ns2);
>> +	t2 = odp_time_local_val(ns2);
>>   	diff = odp_time_diff(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
>> -	nsdiff = odp_time_to_ns(diff);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
>> +	nsdiff = odp_time_val_to_ns(diff);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>> @@ -168,9 +195,9 @@ void time_test_odp_diff(void)
>>
>>   	/* same time has to diff to 0 */
>>   	diff = odp_time_diff(t2, t2);
>> -	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0);
>> +	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) == 0);
>>
>> -	diff = odp_time_diff(t2, ODP_TIME_NULL);
>> +	diff = odp_time_diff(t2, ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(odp_time_cmp(t2, diff) == 0);
>>   }
>>
>> @@ -184,12 +211,12 @@ void time_test_odp_sum(void)
>>   	/* sum timestamp and interval */
>>   	t1 = odp_time_local();
>>   	ns2 = 103;
>> -	t2 = odp_time_local_from_ns(ns2);
>> +	t2 = odp_time_local_val(ns2);
>>   	ns1 = odp_time_to_ns(t1);
>>   	ns = ns1 + ns2;
>>
>>   	sum = odp_time_sum(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>>   	nssum = odp_time_to_ns(sum);
>>
>>   	upper_limit = ns + TOLERANCE;
>> @@ -198,19 +225,19 @@ void time_test_odp_sum(void)
>>
>>   	/* sum intervals */
>>   	ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS;
>> -	t1 = odp_time_local_from_ns(ns1);
>> +	t1 = odp_time_local_val(ns1);
>>   	ns = ns1 + ns2;
>>
>>   	sum = odp_time_sum(t2, t1);
>> -	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
>> -	nssum = odp_time_to_ns(sum);
>> +	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
>> +	nssum = odp_time_val_to_ns(sum);
>>
>>   	upper_limit = ns + TOLERANCE;
>>   	lower_limit = ns - TOLERANCE;
>>   	CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit));
>>
>>   	/* test on 0 */
>> -	sum = odp_time_sum(t2, ODP_TIME_NULL);
>> +	sum = odp_time_sum(t2, ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(odp_time_cmp(t2, sum) == 0);
>>   }
>>
>> @@ -235,7 +262,7 @@ void time_test_odp_to_u64(void)
>>
>>   	CU_ASSERT(val2 > val1);
>>
>> -	val1 = odp_time_to_u64(ODP_TIME_NULL);
>> +	val1 = odp_time_to_u64(ODP_TIME_NULL_VAL);
>>   	CU_ASSERT(val1 == 0);
>>   }
>>
>> --
>> 1.9.1
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
diff mbox

Patch

diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 2de530d..ddae7c0 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -594,7 +594,7 @@  static void print_global_stats(int num_workers)
 	while (odp_thrmask_worker(&thrd_mask) < num_workers)
 		continue;
 
-	wait = odp_time_local_from_ns(verbose_interval * ODP_TIME_SEC_IN_NS);
+	wait = odp_time_local_val(verbose_interval * ODP_TIME_SEC_IN_NS);
 	next = odp_time_sum(odp_time_local(), wait);
 
 	while (odp_thrmask_worker(&thrd_mask) == num_workers) {
diff --git a/include/odp/api/time.h b/include/odp/api/time.h
index 3228879..9a5916b 100644
--- a/include/odp/api/time.h
+++ b/include/odp/api/time.h
@@ -37,15 +37,16 @@  extern "C" {
  */
 
 /**
- * @def ODP_TIME_NULL
- * Zero time stamp
+ * @def ODP_TIME_NULL_VAL
+ * Zero time interval
  */
 
 /**
  * Current local time
  *
  * Returns current local time stamp value. The local time source provides high
- * resolution time and is monotonic.
+ * resolution time and is monotonic. The local time is wall time that means it's
+ * local for each thread.
  *
  * @return Local time stamp.
  */
@@ -57,7 +58,9 @@  odp_time_t odp_time_local(void);
  * @param t2    Second time stamp
  * @param t1    First time stamp
  *
- * @return Difference of time stamps
+ * @return Difference of time stamps ot intervals. Diff of timestamp and
+ * interval results in timestamp.
+ *
  */
 odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
 
@@ -68,6 +71,9 @@  odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1);
  * @param t2    Time stamp
  *
  * @return Sum of time stamps
+ *
+ * @note Sum of two timestamp shouldn't be used, only timestamp and interval or
+ * two intervals. Sum of timestamp and interval results in timestamp.
  */
 odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2);
 
@@ -90,12 +96,28 @@  uint64_t odp_time_to_ns(odp_time_t time);
 odp_time_t odp_time_local_from_ns(uint64_t ns);
 
 /**
+ * Convert nanoseconds to interval of local time
+ *
+ * @param ns	Time in nanoseconds
+ */
+odp_time_t odp_time_local_val(uint64_t ns);
+
+/**
+ * Convert time interval to nanoseconds
+ *
+ * @param val	Time interval
+ */
+uint64_t odp_time_val_to_ns(odp_time_t val);
+
+/**
  * Compare two times
  *
  * @param t2    Second time
  * @param t1    First time
  *
  * @retval <0 if t2 < t1, >0 if t1 = t2, 1 if t2 > t1
+ *
+ * @note Compare two timestamps or two intervals
  */
 int odp_time_cmp(odp_time_t t2, odp_time_t t1);
 
diff --git a/platform/linux-generic/include/odp/plat/time_types.h b/platform/linux-generic/include/odp/plat/time_types.h
index e5765ec..ccf6580 100644
--- a/platform/linux-generic/include/odp/plat/time_types.h
+++ b/platform/linux-generic/include/odp/plat/time_types.h
@@ -23,9 +23,9 @@  extern "C" {
 
 typedef struct timespec odp_time_t;
 
-odp_time_t odp_time_null(void);
+odp_time_t odp_time_null_val(void);
 
-#define ODP_TIME_NULL	odp_time_null()
+#define ODP_TIME_NULL_VAL	odp_time_null_val()
 
 /**
  * @}
diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index 14ba159..baff135 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_local_init(void);
+
 void _odp_flush_caches(void);
 
 #ifdef __cplusplus
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 3017876..6a3440c 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -603,7 +603,7 @@  static int schedule_loop(odp_queue_t *out_queue, uint64_t wait,
 			break;
 
 		if (first) {
-			wtime = odp_time_local_from_ns(wait);
+			wtime = odp_time_local_val(wait);
 			next = odp_time_sum(odp_time_local(), wtime);
 			first = 0;
 			continue;
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 73b2dcb..c82f974 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -11,6 +11,30 @@ 
 #include <odp/hints.h>
 #include <odp_debug_internal.h>
 
+static __thread uint64_t start_local_ns;
+
+static inline
+odp_time_t _odp_time_local_val(uint64_t ns)
+{
+	struct timespec val;
+
+	val.tv_sec = ns / ODP_TIME_SEC_IN_NS;
+	val.tv_nsec = ns % ODP_TIME_SEC_IN_NS;
+
+	return val;
+}
+
+static inline
+uint64_t _odp_time_val_to_ns(odp_time_t val)
+{
+	uint64_t ns;
+
+	ns = val.tv_sec * ODP_TIME_SEC_IN_NS;
+	ns += val.tv_nsec;
+
+	return ns;
+}
+
 odp_time_t odp_time_local(void)
 {
 	int ret;
@@ -38,24 +62,30 @@  odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1)
 	return time;
 }
 
+uint64_t odp_time_val_to_ns(odp_time_t val)
+{
+	return _odp_time_val_to_ns(val);
+}
+
 uint64_t odp_time_to_ns(odp_time_t time)
 {
 	uint64_t ns;
 
-	ns = time.tv_sec * ODP_TIME_SEC_IN_NS;
-	ns += time.tv_nsec;
+	ns = _odp_time_val_to_ns(time);
+	ns -= start_local_ns;
 
 	return ns;
 }
 
 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;
+	ns += start_local_ns;
+	return _odp_time_local_val(ns);
+}
 
-	return time;
+odp_time_t odp_time_local_val(uint64_t ns)
+{
+	return _odp_time_local_val(ns);
 }
 
 int odp_time_cmp(odp_time_t t2, odp_time_t t1)
@@ -96,11 +126,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 _odp_time_val_to_ns(time) / resolution;
 }
 
-odp_time_t odp_time_null(void)
+odp_time_t odp_time_null_val(void)
 {
 	return (struct timespec) {0, 0};
 }
 
+int odp_time_local_init(void)
+{
+	int ret;
+	struct timespec time;
+
+	ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+	start_local_ns = ret ? 0 : _odp_time_val_to_ns(time);
+
+	return ret;
+}
diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c
index 3d37ae1..e1f65e4 100644
--- a/test/performance/odp_pktio_perf.c
+++ b/test/performance/odp_pktio_perf.c
@@ -310,7 +310,7 @@  static void *run_thread_tx(void *arg)
 	uint32_t batch_len;
 	int unsent_pkts = 0;
 	odp_event_t  tx_event[BATCH_LEN_MAX];
-	odp_time_t idle_start = ODP_TIME_NULL;
+	odp_time_t idle_start = ODP_TIME_NULL_VAL;
 
 	thread_args_t *targs = arg;
 
@@ -328,10 +328,10 @@  static void *run_thread_tx(void *arg)
 	if (outq == ODP_QUEUE_INVALID)
 		LOG_ABORT("Failed to get output queue for thread %d\n", thr_id);
 
-	burst_gap = odp_time_local_from_ns(
+	burst_gap = odp_time_local_val(
 			ODP_TIME_SEC_IN_NS / (targs->pps / targs->batch_len));
 	send_duration =
-		odp_time_local_from_ns(targs->duration * ODP_TIME_SEC_IN_NS);
+		odp_time_local_val(targs->duration * ODP_TIME_SEC_IN_NS);
 
 	odp_barrier_wait(&globals->tx_barrier);
 
@@ -343,18 +343,18 @@  static void *run_thread_tx(void *arg)
 
 		if (odp_time_cmp(burst_gap_end, cur_time) > 0) {
 			cur_time = odp_time_local();
-			if (!odp_time_cmp(idle_start, ODP_TIME_NULL))
+			if (!odp_time_cmp(idle_start, ODP_TIME_NULL_VAL))
 				idle_start = cur_time;
 			continue;
 		}
 
-		if (odp_time_cmp(idle_start, ODP_TIME_NULL) > 0) {
+		if (odp_time_cmp(idle_start, ODP_TIME_NULL_VAL) > 0) {
 			odp_time_t diff = odp_time_diff(cur_time, idle_start);
 
 			stats->s.idle_ticks =
 				odp_time_sum(diff, stats->s.idle_ticks);
 
-			idle_start = ODP_TIME_NULL;
+			idle_start = ODP_TIME_NULL_VAL;
 		}
 
 		burst_gap_end = odp_time_sum(burst_gap_end, burst_gap);
@@ -375,7 +375,7 @@  static void *run_thread_tx(void *arg)
 	       " AllocFail %-6"PRIu64" Idle %"PRIu64"ms\n",
 	       thr_id, stats->s.tx_cnt,
 	       stats->s.enq_failures, stats->s.alloc_failures,
-	       odp_time_to_ns(stats->s.idle_ticks) /
+	       odp_time_val_to_ns(stats->s.idle_ticks) /
 	       (uint64_t)ODP_TIME_MSEC_IN_NS);
 
 	return NULL;
@@ -595,13 +595,13 @@  static int setup_txrx_masks(odp_cpumask_t *thd_mask_tx,
  */
 static void busy_loop_ns(uint64_t wait_ns)
 {
-	odp_time_t diff;
-	odp_time_t start_time = odp_time_local();
-	odp_time_t wait = odp_time_local_from_ns(wait_ns);
+	odp_time_t wait = odp_time_local_val(wait_ns);
+	odp_time_t cur = odp_time_local();
+	odp_time_t end_time = odp_time_sum(cur, wait);
 
 	do {
-		diff = odp_time_diff(odp_time_local(), start_time);
-	} while (odp_time_cmp(wait, diff) > 0);
+		cur = odp_time_local();
+	} while (odp_time_cmp(end_time, cur) > 0);
 }
 
 /*
diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index aee3a7d..6d7e954 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -339,7 +339,7 @@  static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
 	odp_time_t wait, end;
 	odp_event_t ev;
 
-	wait = odp_time_local_from_ns(ns);
+	wait = odp_time_local_val(ns);
 	end = odp_time_sum(odp_time_local(), wait);
 	do {
 		ev = odp_queue_deq(queue);
@@ -359,7 +359,7 @@  static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
 	uint64_t wait;
 
 	wait = odp_schedule_wait_time(ns);
-	wait_time = odp_time_local_from_ns(ns);
+	wait_time = odp_time_local_val(ns);
 	end = odp_time_sum(odp_time_local(), wait_time);
 	do {
 		pkt = ODP_PACKET_INVALID;
diff --git a/test/validation/scheduler/scheduler.c b/test/validation/scheduler/scheduler.c
index a562a8a..58f93e0 100644
--- a/test/validation/scheduler/scheduler.c
+++ b/test/validation/scheduler/scheduler.c
@@ -718,7 +718,7 @@  static void *schedule_common_(void *arg)
 			CU_ASSERT(from != ODP_QUEUE_INVALID);
 			if (locked) {
 				int cnt;
-				odp_time_t time = ODP_TIME_NULL;
+				odp_time_t time = ODP_TIME_NULL_VAL;
 				/* Do some work here to keep the thread busy */
 				for (cnt = 0; cnt < 1000; cnt++)
 					time = odp_time_sum(time,
diff --git a/test/validation/time/time.c b/test/validation/time/time.c
index 8f5dfe6..4386c34 100644
--- a/test/validation/time/time.c
+++ b/test/validation/time/time.c
@@ -18,6 +18,7 @@  void time_test_odp_conversion(void)
 	odp_time_t time;
 	uint64_t upper_limit, lower_limit;
 
+	/* test timestamp conversions */
 	ns1 = 100;
 	time = odp_time_local_from_ns(ns1);
 
@@ -34,8 +35,18 @@  void time_test_odp_conversion(void)
 
 	ns2 = odp_time_to_ns(time);
 
-	/* need to check within arithmetic tolerance that the same
-	 * value in ns is returned after conversions */
+	/*
+	 * need to check within arithmetic tolerance that the same
+	 * value in ns is returned after conversions
+	 */
+	upper_limit = ns1 + TOLERANCE;
+	lower_limit = ns1 - TOLERANCE;
+	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
+
+	/* test time vals conversions */
+	time = odp_time_local_val(ns1);
+	ns2 = odp_time_val_to_ns(time);
+
 	upper_limit = ns1 + TOLERANCE;
 	lower_limit = ns1 - TOLERANCE;
 	CU_ASSERT((ns2 <= upper_limit) && (ns2 >= lower_limit));
@@ -75,6 +86,7 @@  void time_test_odp_cmp(void)
 	volatile int count = 0;
 	odp_time_t t1, t2, t3;
 
+	/* test compare of timestamps */
 	t1 = odp_time_local();
 
 	while (count < BUSY_LOOP_CNT) {
@@ -105,8 +117,23 @@  void time_test_odp_cmp(void)
 	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
 	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
 
-	t1 = odp_time_local_from_ns(0);
-	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL) == 0);
+	t1 = odp_time_local_val(0);
+	CU_ASSERT(odp_time_cmp(t1, ODP_TIME_NULL_VAL) == 0);
+
+	/* test compare of time intervals */
+	t1 = odp_time_local_val(15);
+	t2 = odp_time_local_val(23);
+	t3 = odp_time_local_val(51);
+
+	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
+	CU_ASSERT(odp_time_cmp(t3, t2) > 0);
+	CU_ASSERT(odp_time_cmp(t3, t1) > 0);
+	CU_ASSERT(odp_time_cmp(t1, t2) < 0);
+	CU_ASSERT(odp_time_cmp(t2, t3) < 0);
+	CU_ASSERT(odp_time_cmp(t1, t3) < 0);
+	CU_ASSERT(odp_time_cmp(t1, t1) == 0);
+	CU_ASSERT(odp_time_cmp(t2, t2) == 0);
+	CU_ASSERT(odp_time_cmp(t3, t3) == 0);
 }
 
 /* check that a time difference gives a reasonable result */
@@ -129,12 +156,12 @@  void time_test_odp_diff(void)
 	CU_ASSERT(odp_time_cmp(t2, t1) > 0);
 
 	diff = odp_time_diff(t2, t1);
-	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
+	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
 
 	ns1 = odp_time_to_ns(t1);
 	ns2 = odp_time_to_ns(t2);
 	ns = ns2 - ns1;
-	nsdiff = odp_time_to_ns(diff);
+	nsdiff = odp_time_val_to_ns(diff);
 
 	upper_limit = ns + TOLERANCE;
 	lower_limit = ns - TOLERANCE;
@@ -142,11 +169,11 @@  void time_test_odp_diff(void)
 
 	/* test timestamp and interval diff */
 	ns1 = 54;
-	t1 = odp_time_local_from_ns(ns1);
+	t1 = odp_time_local_val(ns1);
 	ns = ns2 - ns1;
 
 	diff = odp_time_diff(t2, t1);
-	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
+	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
 	nsdiff = odp_time_to_ns(diff);
 
 	upper_limit = ns + TOLERANCE;
@@ -157,10 +184,10 @@  void time_test_odp_diff(void)
 	ns2 = 60 * 10 * ODP_TIME_SEC_IN_NS;
 	ns = ns2 - ns1;
 
-	t2 = odp_time_local_from_ns(ns2);
+	t2 = odp_time_local_val(ns2);
 	diff = odp_time_diff(t2, t1);
-	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) > 0);
-	nsdiff = odp_time_to_ns(diff);
+	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) > 0);
+	nsdiff = odp_time_val_to_ns(diff);
 
 	upper_limit = ns + TOLERANCE;
 	lower_limit = ns - TOLERANCE;
@@ -168,9 +195,9 @@  void time_test_odp_diff(void)
 
 	/* same time has to diff to 0 */
 	diff = odp_time_diff(t2, t2);
-	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL) == 0);
+	CU_ASSERT(odp_time_cmp(diff, ODP_TIME_NULL_VAL) == 0);
 
-	diff = odp_time_diff(t2, ODP_TIME_NULL);
+	diff = odp_time_diff(t2, ODP_TIME_NULL_VAL);
 	CU_ASSERT(odp_time_cmp(t2, diff) == 0);
 }
 
@@ -184,12 +211,12 @@  void time_test_odp_sum(void)
 	/* sum timestamp and interval */
 	t1 = odp_time_local();
 	ns2 = 103;
-	t2 = odp_time_local_from_ns(ns2);
+	t2 = odp_time_local_val(ns2);
 	ns1 = odp_time_to_ns(t1);
 	ns = ns1 + ns2;
 
 	sum = odp_time_sum(t2, t1);
-	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
+	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
 	nssum = odp_time_to_ns(sum);
 
 	upper_limit = ns + TOLERANCE;
@@ -198,19 +225,19 @@  void time_test_odp_sum(void)
 
 	/* sum intervals */
 	ns1 = 60 * 13 * ODP_TIME_SEC_IN_NS;
-	t1 = odp_time_local_from_ns(ns1);
+	t1 = odp_time_local_val(ns1);
 	ns = ns1 + ns2;
 
 	sum = odp_time_sum(t2, t1);
-	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL) > 0);
-	nssum = odp_time_to_ns(sum);
+	CU_ASSERT(odp_time_cmp(sum, ODP_TIME_NULL_VAL) > 0);
+	nssum = odp_time_val_to_ns(sum);
 
 	upper_limit = ns + TOLERANCE;
 	lower_limit = ns - TOLERANCE;
 	CU_ASSERT((nssum <= upper_limit) && (nssum >= lower_limit));
 
 	/* test on 0 */
-	sum = odp_time_sum(t2, ODP_TIME_NULL);
+	sum = odp_time_sum(t2, ODP_TIME_NULL_VAL);
 	CU_ASSERT(odp_time_cmp(t2, sum) == 0);
 }
 
@@ -235,7 +262,7 @@  void time_test_odp_to_u64(void)
 
 	CU_ASSERT(val2 > val1);
 
-	val1 = odp_time_to_u64(ODP_TIME_NULL);
+	val1 = odp_time_to_u64(ODP_TIME_NULL_VAL);
 	CU_ASSERT(val1 == 0);
 }