xref: /f-stack/dpdk/app/test/test_cycles.c (revision 0c6bd470)
14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright(c) 2010-2014 Intel Corporation
34418919fSjohnjiang  */
44418919fSjohnjiang 
54418919fSjohnjiang #include <stdio.h>
64418919fSjohnjiang #include <stdint.h>
74418919fSjohnjiang 
84418919fSjohnjiang #include <rte_common.h>
94418919fSjohnjiang #include <rte_cycles.h>
104418919fSjohnjiang 
114418919fSjohnjiang #include "test.h"
124418919fSjohnjiang 
134418919fSjohnjiang #define N 10000
144418919fSjohnjiang 
154418919fSjohnjiang /*
164418919fSjohnjiang  * Cycles test
174418919fSjohnjiang  * ===========
184418919fSjohnjiang  *
194418919fSjohnjiang  * - Loop N times and check that the timer always increments and
204418919fSjohnjiang  *   never decrements during this loop.
214418919fSjohnjiang  *
224418919fSjohnjiang  * - Wait one second using rte_usleep() and check that the increment
234418919fSjohnjiang  *   of cycles is correct with regard to the frequency of the timer.
244418919fSjohnjiang  */
254418919fSjohnjiang 
264418919fSjohnjiang static int
check_wait_one_second(void)274418919fSjohnjiang check_wait_one_second(void)
284418919fSjohnjiang {
294418919fSjohnjiang 	uint64_t cycles, prev_cycles;
304418919fSjohnjiang 	uint64_t hz = rte_get_timer_hz();
314418919fSjohnjiang 	uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */
324418919fSjohnjiang 
334418919fSjohnjiang 	/* check that waiting 1 second is precise */
344418919fSjohnjiang 	prev_cycles = rte_get_timer_cycles();
354418919fSjohnjiang 	rte_delay_us(1000000);
364418919fSjohnjiang 	cycles = rte_get_timer_cycles();
374418919fSjohnjiang 
384418919fSjohnjiang 	if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) {
394418919fSjohnjiang 		printf("delay_us is not accurate: too long\n");
404418919fSjohnjiang 		return -1;
414418919fSjohnjiang 	}
424418919fSjohnjiang 	if ((uint64_t)(cycles - prev_cycles) < (hz - max_inc)) {
434418919fSjohnjiang 		printf("delay_us is not accurate: too short\n");
444418919fSjohnjiang 		return -1;
454418919fSjohnjiang 	}
464418919fSjohnjiang 
474418919fSjohnjiang 	return 0;
484418919fSjohnjiang }
494418919fSjohnjiang 
504418919fSjohnjiang static int
test_cycles(void)514418919fSjohnjiang test_cycles(void)
524418919fSjohnjiang {
534418919fSjohnjiang 	unsigned i;
544418919fSjohnjiang 	uint64_t start_cycles, cycles, prev_cycles;
554418919fSjohnjiang 	uint64_t hz = rte_get_timer_hz();
564418919fSjohnjiang 	uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */
574418919fSjohnjiang 
584418919fSjohnjiang 	/* check that the timer is always incrementing */
594418919fSjohnjiang 	start_cycles = rte_get_timer_cycles();
604418919fSjohnjiang 	prev_cycles = start_cycles;
614418919fSjohnjiang 	for (i=0; i<N; i++) {
624418919fSjohnjiang 		cycles = rte_get_timer_cycles();
634418919fSjohnjiang 		if ((uint64_t)(cycles - prev_cycles) > max_inc) {
644418919fSjohnjiang 			printf("increment too high or going backwards\n");
654418919fSjohnjiang 			return -1;
664418919fSjohnjiang 		}
674418919fSjohnjiang 		prev_cycles = cycles;
684418919fSjohnjiang 	}
694418919fSjohnjiang 
704418919fSjohnjiang 	return check_wait_one_second();
714418919fSjohnjiang }
724418919fSjohnjiang 
734418919fSjohnjiang REGISTER_TEST_COMMAND(cycles_autotest, test_cycles);
744418919fSjohnjiang 
754418919fSjohnjiang /*
764418919fSjohnjiang  * One second precision test with rte_delay_us_sleep.
774418919fSjohnjiang  */
784418919fSjohnjiang 
794418919fSjohnjiang static int
test_delay_us_sleep(void)804418919fSjohnjiang test_delay_us_sleep(void)
814418919fSjohnjiang {
82*0c6bd470Sfengbojiang 	int rv;
83*0c6bd470Sfengbojiang 
844418919fSjohnjiang 	rte_delay_us_callback_register(rte_delay_us_sleep);
85*0c6bd470Sfengbojiang 	rv = check_wait_one_second();
86*0c6bd470Sfengbojiang 	/* restore original delay function */
87*0c6bd470Sfengbojiang 	rte_delay_us_callback_register(rte_delay_us_block);
88*0c6bd470Sfengbojiang 
89*0c6bd470Sfengbojiang 	return rv;
904418919fSjohnjiang }
914418919fSjohnjiang 
924418919fSjohnjiang REGISTER_TEST_COMMAND(delay_us_sleep_autotest, test_delay_us_sleep);
934418919fSjohnjiang 
944418919fSjohnjiang /*
954418919fSjohnjiang  * rte_delay_us_callback test
964418919fSjohnjiang  *
974418919fSjohnjiang  * - check if callback is correctly registered/unregistered
984418919fSjohnjiang  *
994418919fSjohnjiang  */
1004418919fSjohnjiang 
1014418919fSjohnjiang static unsigned int pattern;
my_rte_delay_us(unsigned int us)1024418919fSjohnjiang static void my_rte_delay_us(unsigned int us)
1034418919fSjohnjiang {
1044418919fSjohnjiang 	pattern += us;
1054418919fSjohnjiang }
1064418919fSjohnjiang 
1074418919fSjohnjiang static int
test_user_delay_us(void)1084418919fSjohnjiang test_user_delay_us(void)
1094418919fSjohnjiang {
1104418919fSjohnjiang 	pattern = 0;
1114418919fSjohnjiang 
1124418919fSjohnjiang 	rte_delay_us(2);
1134418919fSjohnjiang 	if (pattern != 0)
1144418919fSjohnjiang 		return -1;
1154418919fSjohnjiang 
1164418919fSjohnjiang 	/* register custom delay function */
1174418919fSjohnjiang 	rte_delay_us_callback_register(my_rte_delay_us);
1184418919fSjohnjiang 
1194418919fSjohnjiang 	rte_delay_us(2);
1204418919fSjohnjiang 	if (pattern != 2)
1214418919fSjohnjiang 		return -1;
1224418919fSjohnjiang 
1234418919fSjohnjiang 	rte_delay_us(3);
1244418919fSjohnjiang 	if (pattern != 5)
1254418919fSjohnjiang 		return -1;
1264418919fSjohnjiang 
1274418919fSjohnjiang 	/* restore original delay function */
1284418919fSjohnjiang 	rte_delay_us_callback_register(rte_delay_us_block);
1294418919fSjohnjiang 
1304418919fSjohnjiang 	rte_delay_us(3);
1314418919fSjohnjiang 	if (pattern != 5)
1324418919fSjohnjiang 		return -1;
1334418919fSjohnjiang 
1344418919fSjohnjiang 	return 0;
1354418919fSjohnjiang }
1364418919fSjohnjiang 
1374418919fSjohnjiang REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us);
138