[API-NEXT,3/6] test: time: add tick tests

Message ID 20170528192302.56363-3-brian.brooks@arm.com
State New
Headers show
Series
  • [API-NEXT,1/6] api: time: add odp_tick_t
Related show

Commit Message

Brian Brooks May 28, 2017, 7:22 p.m.
Signed-off-by: Brian Brooks <brian.brooks@arm.com>

Reviewed-by: Ola Liljedahl <ola.liljedahl@arm.com>

---
 test/common_plat/validation/api/time/time.c | 69 +++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

-- 
2.13.0

Patch hide | download patch | download mbox

diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c
index e2ca2e17..0424481a 100644
--- a/test/common_plat/validation/api/time/time.c
+++ b/test/common_plat/validation/api/time/time.c
@@ -3,6 +3,8 @@ 
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#define _GNU_SOURCE
+#include <time.h>
 
 #include <odp_api.h>
 #include "odp_cunit_common.h"
@@ -438,6 +440,71 @@  static void time_test_global_accuracy(void)
 	time_test_accuracy(odp_time_global, odp_time_global_from_ns);
 }
 
+#define ABS(n) ((n) > 0 ? (n) : -(n))
+
+/* Returns the current time (in nanoseconds) from the system clock. */
+static uint64_t sys_clock_now(void)
+{
+	struct timespec ts;
+	uint64_t ns;
+
+	if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
+		perror("clock_gettime");
+		return 0;
+	}
+
+	ns  = ts.tv_sec * NSEC_PER_SEC;
+	ns += ts.tv_nsec;
+	return ns;
+}
+
+/* Suspend the current thread from execution for some amount of microseconds. */
+static void thread_usleep(int us)
+{
+	struct timespec ts;
+
+	ts.tv_sec  = us / USEC_PER_SEC;
+	ts.tv_nsec = NSEC_PER_USEC * (us % USEC_PER_SEC);
+
+	while (nanosleep(&ts, &ts) != 0 && errno == EINTR)
+		; /* keep sleeping.. */
+}
+
+/* Check that converting between tick and nanosecond values is stable. */
+static void tick_conversions(void)
+{
+	odp_tick_t t1 = odp_tick_now();
+	odp_tick_t t2 = t1 + odp_ticks_from_ns(NSEC_PER_SEC);
+	uint64_t ns = odp_ns_from_ticks(t2 - t1);
+
+	CU_ASSERT(ns == NSEC_PER_SEC);
+}
+
+/* Test that measuring time using ticks is no more than some
+ * amount of nanoseconds difference from measuring time using
+ * the OS clock. */
+#define TICK_THRESHOLD_NS 1000
+
+static void tick_accuracy(void)
+{
+	uint64_t s1 = sys_clock_now();
+	odp_tick_t t1 = odp_tick_now();
+
+	thread_usleep(100);
+
+	odp_tick_t t2 = odp_tick_now();
+	uint64_t s2 = sys_clock_now();
+
+	uint64_t s_delta = s2 - s1;
+	uint64_t t_delta = odp_ns_from_ticks(t2 - t1);
+
+	CU_ASSERT(s_delta >= 100 * NSEC_PER_USEC);
+	CU_ASSERT(t_delta >= 100 * NSEC_PER_USEC);
+
+	CU_ASSERT(ABS((int64_t)t_delta - (int64_t)s_delta)
+		  <= TICK_THRESHOLD_NS);
+}
+
 odp_testinfo_t time_suite_time[] = {
 	ODP_TEST_INFO(time_test_constants),
 	ODP_TEST_INFO(time_test_local_res),
@@ -456,6 +523,8 @@  odp_testinfo_t time_suite_time[] = {
 	ODP_TEST_INFO(time_test_global_sum),
 	ODP_TEST_INFO(time_test_global_wait_until),
 	ODP_TEST_INFO(time_test_global_accuracy),
+	ODP_TEST_INFO(tick_conversions),
+	ODP_TEST_INFO(tick_accuracy),
 	ODP_TEST_INFO_NULL
 };