diff mbox

[v3] validation: system: add validation tests for odp_cpu_cycles_* calls

Message ID 1452861175-25908-1-git-send-email-ivan.khoronzhuk@linaro.org
State New
Headers show

Commit Message

Ivan Khoronzhuk Jan. 15, 2016, 12:32 p.m. UTC
https://bugs.linaro.org/show_bug.cgi?id=1906

Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---

Since v2:
- added c <= max
- replaced etalon on tmp
- added msg about skip
- handled resolution wrap

 test/validation/system/system.c | 133 ++++++++++++++++++++++++++++++++++++++++
 test/validation/system/system.h |   4 ++
 2 files changed, 137 insertions(+)

Comments

Ivan Khoronzhuk Jan. 15, 2016, 1:55 p.m. UTC | #1
On 15.01.16 15:34, Savolainen, Petri (Nokia - FI/Espoo) wrote:
>
>
>> -----Original Message-----
>> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
>> Sent: Friday, January 15, 2016 2:33 PM
>> To: lng-odp@lists.linaro.org
>> Cc: Savolainen, Petri (Nokia - FI/Espoo); Ivan Khoronzhuk
>> Subject: [lng-odp] [PATCH v3] validation: system: add validation tests for
>> odp_cpu_cycles_* calls
>>
>> https://bugs.linaro.org/show_bug.cgi?id=1906
>>
>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> ---
>>
>> Since v2:
>> - added c <= max
>> - replaced etalon on tmp
>> - added msg about skip
>> - handled resolution wrap
>>
>>   test/validation/system/system.c | 133
>> ++++++++++++++++++++++++++++++++++++++++
>>   test/validation/system/system.h |   4 ++
>>   2 files changed, 137 insertions(+)
>>
>> diff --git a/test/validation/system/system.c
>> b/test/validation/system/system.c
>> index 7dc2cc0..2cf5d29 100644
>> --- a/test/validation/system/system.c
>> +++ b/test/validation/system/system.c
>> @@ -10,6 +10,8 @@
>>   #include "test_debug.h"
>>   #include "system.h"
>>
>> +#define TRY_NUM			80
>> +
>>   void system_test_odp_version_numbers(void)
>>   {
>>   	int char_ok = 0;
>> @@ -40,6 +42,133 @@ void system_test_odp_cpu_count(void)
>>   	CU_ASSERT(0 < cpus);
>>   }
>>
>> +void system_test_odp_cpu_cycles(void)
>> +{
>> +	uint64_t c2, c1;
>> +
>> +	c1 = odp_cpu_cycles();
>> +	odp_time_wait_ns(100);
>> +	c2 = odp_cpu_cycles();
>> +
>> +	CU_ASSERT(c2 != c1);
>> +}
>> +
>> +void system_test_odp_cpu_cycles_max(void)
>> +{
>> +	uint64_t c2, c1;
>> +	uint64_t max1, max2;
>> +
>> +	max1 = odp_cpu_cycles_max();
>> +	odp_time_wait_ns(100);
>> +	max2 = odp_cpu_cycles_max();
>> +
>> +	CU_ASSERT(max1 >= UINT32_MAX / 2);
>> +	CU_ASSERT(max1 == max2);
>> +
>> +	c1 = odp_cpu_cycles();
>> +	odp_time_wait_ns(1000);
>> +	c2 = odp_cpu_cycles();
>> +
>> +	CU_ASSERT(c1 <= max1 && c2 <= max1);
>> +}
>> +
>> +void system_test_odp_cpu_cycles_diff(void)
>> +{
>> +	int i;
>> +	uint64_t c2, c1;
>> +	uint64_t tmp, diff;
>> +
>> +	c2 = 100;
>> +	c1 = 39;
>> +
>> +	diff = odp_cpu_cycles_diff(c2, c2);
>> +	CU_ASSERT(diff == 0);
>> +
>> +	tmp = c2 - c1;
>> +	diff = odp_cpu_cycles_diff(c2, c1);
>> +	CU_ASSERT(diff == tmp);
>> +
>> +	tmp = c1 + (odp_cpu_cycles_max() - c2) + 1;
>> +	diff = odp_cpu_cycles_diff(c1, c2);
>> +	CU_ASSERT(diff == tmp);
>> +
>> +	c1 = odp_cpu_cycles();
>> +	if (!(odp_cpu_cycles_max() <= UINT32_MAX ||
>> +	      (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) {
>> +		printf("wrap detection is skipped...");
>
>
> Sorry about another iteration, but after thinking this again...
np.

  Maybe it's better to run the test under in any case and print into the log if wrap was tested or not. Missing the wrap is the common case with 64 bit cpu counters.
Ok.

>
>
>> +		return;
>> +	}
>> +
>> +	/* must handle one wrap */
>> +	for (i = 0; i < TRY_NUM; i++) {
>> +		c1 = odp_cpu_cycles();
>> +		odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i);
>> +		c2 = odp_cpu_cycles();
>> +
>> +		CU_ASSERT(c2 != c1);
>> +
>> +		if (c2 > c1)
>> +			tmp = c2 - c1;
>> +		else
>> +			tmp = c2 + (odp_cpu_cycles_max() - c1) + 1;
>> +
>> +		diff = odp_cpu_cycles_diff(c2, c1);
>> +		CU_ASSERT(diff == tmp);
>> +
>> +		/* wrap is detected and verified */
>> +		if (c2 < c1)
>> +			break;
>> +	}
>> +
>> +	/* wrap has to be detected */
>> +	CU_ASSERT(i < TRY_NUM);
>
> Wrap depends on CPU frequency. On low freq it may take a long time. May be it's better to just print warning if wrap was not tested.
Ok.

>
>
>> +}
>> +
>> +void system_test_odp_cpu_cycles_resolution(void)
>
>
> This resolution test case could be combined with previous one, so that we don't have to wait two times 8 sec (on every 'make check').
In previous test I'm going to increase TRY_NUM to match 16seconds due to low frequency in some cases.
But I like resolution test with loop also.
Here no need to wait so long time, anyway resolution while wrap is verified before loop.
And in loop, decrease TRY_NUM to 10, thus it'll take ~ 1 second.

>
>
>
>> +{
>> +	int i;
>> +	uint64_t rest;
>> +	uint64_t res, diff;
>> +	uint64_t c2, c1, max;
>> +
>> +	res = odp_cpu_cycles_resolution();
>> +	CU_ASSERT(res != 0);
>> +	CU_ASSERT(res < 500);
>
> Resolution could be larger than 500 cycles, but it cannot be larger than max cycles (or some fraction of that e.g. max / 1024).
Ok. max / 1024;

>
>
> -Petri
>
>> +
>> +	/* check resolution for wrap */
>> +	max = odp_cpu_cycles_max();
>> +	c1 = max - 2 * res;
>> +	c2 = odp_cpu_cycles();
here can happen that c2 is between c1 and max.
I should take it into account also.

>> +	diff = odp_cpu_cycles_diff(c2, c1);
>> +	rest = diff % res;
>> +	CU_ASSERT(rest == 0);
>> +
>> +	/*
>> +	 * must be a multiple of resolution in
>> +	 * whole interval till wrap, in another
>> +	 * case resolution is set incorrectly
>> +	 */
>> +	for (i = 0; i < TRY_NUM; i++) {
>> +		c1 = odp_cpu_cycles();
>> +		odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i);
>> +		c2 = odp_cpu_cycles();
>> +
>> +		diff = odp_cpu_cycles_diff(c2, c1);
>> +		rest = diff % res;
>> +		CU_ASSERT(rest == 0);
>> +
>> +		rest = c1 % res;
>> +		CU_ASSERT(rest == 0);
>> +
>> +		rest = c2 % res;
>> +		CU_ASSERT(rest == 0);
>> +
>> +		/* wrap is detected and verified */
>> +		if (c2 < c1)
>> +			break;
>> +	}
>> +}
>> +
>>   void system_test_odp_sys_cache_line_size(void)
>>   {
>>   	uint64_t cache_size;
>> @@ -91,6 +220,10 @@ odp_testinfo_t system_suite[] = {
>>   	ODP_TEST_INFO(system_test_odp_sys_page_size),
>>   	ODP_TEST_INFO(system_test_odp_sys_huge_page_size),
>>   	ODP_TEST_INFO(system_test_odp_sys_cpu_hz),
>> +	ODP_TEST_INFO(system_test_odp_cpu_cycles),
>> +	ODP_TEST_INFO(system_test_odp_cpu_cycles_max),
>> +	ODP_TEST_INFO(system_test_odp_cpu_cycles_diff),
>> +	ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution),
>>   	ODP_TEST_INFO_NULL,
>>   };
>>
>> diff --git a/test/validation/system/system.h
>> b/test/validation/system/system.h
>> index 869aaff..0c263f2 100644
>> --- a/test/validation/system/system.h
>> +++ b/test/validation/system/system.h
>> @@ -17,6 +17,10 @@ void system_test_odp_sys_cpu_model_str(void);
>>   void system_test_odp_sys_page_size(void);
>>   void system_test_odp_sys_huge_page_size(void);
>>   void system_test_odp_sys_cpu_hz(void);
>> +void system_test_odp_cpu_cycles_max(void);
>> +void system_test_odp_cpu_cycles(void);
>> +void system_test_odp_cpu_cycles_diff(void);
>> +void system_test_odp_cpu_cycles_resolution(void);
>>
>>   /* test arrays: */
>>   extern odp_testinfo_t system_suite[];
>> --
>> 1.9.1
>
diff mbox

Patch

diff --git a/test/validation/system/system.c b/test/validation/system/system.c
index 7dc2cc0..2cf5d29 100644
--- a/test/validation/system/system.c
+++ b/test/validation/system/system.c
@@ -10,6 +10,8 @@ 
 #include "test_debug.h"
 #include "system.h"
 
+#define TRY_NUM			80
+
 void system_test_odp_version_numbers(void)
 {
 	int char_ok = 0;
@@ -40,6 +42,133 @@  void system_test_odp_cpu_count(void)
 	CU_ASSERT(0 < cpus);
 }
 
+void system_test_odp_cpu_cycles(void)
+{
+	uint64_t c2, c1;
+
+	c1 = odp_cpu_cycles();
+	odp_time_wait_ns(100);
+	c2 = odp_cpu_cycles();
+
+	CU_ASSERT(c2 != c1);
+}
+
+void system_test_odp_cpu_cycles_max(void)
+{
+	uint64_t c2, c1;
+	uint64_t max1, max2;
+
+	max1 = odp_cpu_cycles_max();
+	odp_time_wait_ns(100);
+	max2 = odp_cpu_cycles_max();
+
+	CU_ASSERT(max1 >= UINT32_MAX / 2);
+	CU_ASSERT(max1 == max2);
+
+	c1 = odp_cpu_cycles();
+	odp_time_wait_ns(1000);
+	c2 = odp_cpu_cycles();
+
+	CU_ASSERT(c1 <= max1 && c2 <= max1);
+}
+
+void system_test_odp_cpu_cycles_diff(void)
+{
+	int i;
+	uint64_t c2, c1;
+	uint64_t tmp, diff;
+
+	c2 = 100;
+	c1 = 39;
+
+	diff = odp_cpu_cycles_diff(c2, c2);
+	CU_ASSERT(diff == 0);
+
+	tmp = c2 - c1;
+	diff = odp_cpu_cycles_diff(c2, c1);
+	CU_ASSERT(diff == tmp);
+
+	tmp = c1 + (odp_cpu_cycles_max() - c2) + 1;
+	diff = odp_cpu_cycles_diff(c1, c2);
+	CU_ASSERT(diff == tmp);
+
+	c1 = odp_cpu_cycles();
+	if (!(odp_cpu_cycles_max() <= UINT32_MAX ||
+	      (odp_cpu_cycles_max() - c1) <= UINT32_MAX)) {
+		printf("wrap detection is skipped...");
+		return;
+	}
+
+	/* must handle one wrap */
+	for (i = 0; i < TRY_NUM; i++) {
+		c1 = odp_cpu_cycles();
+		odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i);
+		c2 = odp_cpu_cycles();
+
+		CU_ASSERT(c2 != c1);
+
+		if (c2 > c1)
+			tmp = c2 - c1;
+		else
+			tmp = c2 + (odp_cpu_cycles_max() - c1) + 1;
+
+		diff = odp_cpu_cycles_diff(c2, c1);
+		CU_ASSERT(diff == tmp);
+
+		/* wrap is detected and verified */
+		if (c2 < c1)
+			break;
+	}
+
+	/* wrap has to be detected */
+	CU_ASSERT(i < TRY_NUM);
+}
+
+void system_test_odp_cpu_cycles_resolution(void)
+{
+	int i;
+	uint64_t rest;
+	uint64_t res, diff;
+	uint64_t c2, c1, max;
+
+	res = odp_cpu_cycles_resolution();
+	CU_ASSERT(res != 0);
+	CU_ASSERT(res < 500);
+
+	/* check resolution for wrap */
+	max = odp_cpu_cycles_max();
+	c1 = max - 2 * res;
+	c2 = odp_cpu_cycles();
+	diff = odp_cpu_cycles_diff(c2, c1);
+	rest = diff % res;
+	CU_ASSERT(rest == 0);
+
+	/*
+	 * must be a multiple of resolution in
+	 * whole interval till wrap, in another
+	 * case resolution is set incorrectly
+	 */
+	for (i = 0; i < TRY_NUM; i++) {
+		c1 = odp_cpu_cycles();
+		odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i);
+		c2 = odp_cpu_cycles();
+
+		diff = odp_cpu_cycles_diff(c2, c1);
+		rest = diff % res;
+		CU_ASSERT(rest == 0);
+
+		rest = c1 % res;
+		CU_ASSERT(rest == 0);
+
+		rest = c2 % res;
+		CU_ASSERT(rest == 0);
+
+		/* wrap is detected and verified */
+		if (c2 < c1)
+			break;
+	}
+}
+
 void system_test_odp_sys_cache_line_size(void)
 {
 	uint64_t cache_size;
@@ -91,6 +220,10 @@  odp_testinfo_t system_suite[] = {
 	ODP_TEST_INFO(system_test_odp_sys_page_size),
 	ODP_TEST_INFO(system_test_odp_sys_huge_page_size),
 	ODP_TEST_INFO(system_test_odp_sys_cpu_hz),
+	ODP_TEST_INFO(system_test_odp_cpu_cycles),
+	ODP_TEST_INFO(system_test_odp_cpu_cycles_max),
+	ODP_TEST_INFO(system_test_odp_cpu_cycles_diff),
+	ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution),
 	ODP_TEST_INFO_NULL,
 };
 
diff --git a/test/validation/system/system.h b/test/validation/system/system.h
index 869aaff..0c263f2 100644
--- a/test/validation/system/system.h
+++ b/test/validation/system/system.h
@@ -17,6 +17,10 @@  void system_test_odp_sys_cpu_model_str(void);
 void system_test_odp_sys_page_size(void);
 void system_test_odp_sys_huge_page_size(void);
 void system_test_odp_sys_cpu_hz(void);
+void system_test_odp_cpu_cycles_max(void);
+void system_test_odp_cpu_cycles(void);
+void system_test_odp_cpu_cycles_diff(void);
+void system_test_odp_cpu_cycles_resolution(void);
 
 /* test arrays: */
 extern odp_testinfo_t system_suite[];