xref: /dpdk/app/test/test_common.c (revision c9902a15bd005b6d4fe072cf7b60fe4ee679155f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <inttypes.h>
7 #include <string.h>
8 #include <math.h>
9 #include <rte_common.h>
10 #include <rte_hexdump.h>
11 #include <rte_pause.h>
12 
13 #include "test.h"
14 
15 #define MAX_NUM 1 << 20
16 
17 #define FAIL(x)\
18 	{printf(x "() test failed!\n");\
19 	return -1;}
20 
21 /* this is really a sanity check */
22 static int
23 test_macros(int __rte_unused unused_parm)
24 {
25 #define SMALLER 0x1000U
26 #define BIGGER 0x2000U
27 #define PTR_DIFF BIGGER - SMALLER
28 #define FAIL_MACRO(x)\
29 	{printf(#x "() test failed!\n");\
30 	return -1;}
31 
32 	uintptr_t unused = 0;
33 	unsigned int smaller = SMALLER, bigger  = BIGGER;
34 
35 	RTE_SET_USED(unused);
36 
37 	RTE_SWAP(smaller, bigger);
38 	if (smaller != BIGGER && bigger != SMALLER)
39 		FAIL_MACRO(RTE_SWAP);
40 	if ((uintptr_t)RTE_PTR_ADD(SMALLER, PTR_DIFF) != BIGGER)
41 		FAIL_MACRO(RTE_PTR_ADD);
42 	if ((uintptr_t)RTE_PTR_SUB(BIGGER, PTR_DIFF) != SMALLER)
43 		FAIL_MACRO(RTE_PTR_SUB);
44 	if (RTE_PTR_DIFF(BIGGER, SMALLER) != PTR_DIFF)
45 		FAIL_MACRO(RTE_PTR_DIFF);
46 	if (RTE_MAX(SMALLER, BIGGER) != BIGGER)
47 		FAIL_MACRO(RTE_MAX);
48 	if (RTE_MIN(SMALLER, BIGGER) != SMALLER)
49 		FAIL_MACRO(RTE_MIN);
50 
51 	if (strncmp(RTE_STR(test), "test", sizeof("test")))
52 		FAIL_MACRO(RTE_STR);
53 
54 	return 0;
55 }
56 
57 static int
58 test_bsf(void)
59 {
60 	uint32_t shift, pos;
61 
62 	/* safe versions should be able to handle 0 */
63 	if (rte_bsf32_safe(0, &pos) != 0)
64 		FAIL("rte_bsf32_safe");
65 	if (rte_bsf64_safe(0, &pos) != 0)
66 		FAIL("rte_bsf64_safe");
67 
68 	for (shift = 0; shift < 63; shift++) {
69 		uint32_t val32;
70 		uint64_t val64;
71 
72 		val64 = 1ULL << shift;
73 		if ((uint32_t)rte_bsf64(val64) != shift)
74 			FAIL("rte_bsf64");
75 		if (rte_bsf64_safe(val64, &pos) != 1)
76 			FAIL("rte_bsf64_safe");
77 		if (pos != shift)
78 			FAIL("rte_bsf64_safe");
79 
80 		if (shift > 31)
81 			continue;
82 
83 		val32 = 1U << shift;
84 		if ((uint32_t)rte_bsf32(val32) != shift)
85 			FAIL("rte_bsf32");
86 		if (rte_bsf32_safe(val32, &pos) != 1)
87 			FAIL("rte_bsf32_safe");
88 		if (pos != shift)
89 			FAIL("rte_bsf32_safe");
90 	}
91 
92 	return 0;
93 }
94 
95 static int
96 test_misc(void)
97 {
98 	char memdump[] = "memdump_test";
99 
100 	rte_memdump(stdout, "test", memdump, sizeof(memdump));
101 	rte_hexdump(stdout, "test", memdump, sizeof(memdump));
102 
103 	rte_pause();
104 
105 	return 0;
106 }
107 
108 static int
109 test_align(void)
110 {
111 #define FAIL_ALIGN(x, i, p)\
112 	{printf(x "() test failed: %u %u\n", i, p);\
113 	return -1;}
114 #define FAIL_ALIGN64(x, j, q)\
115 	{printf(x "() test failed: %"PRIu64" %"PRIu64"\n", j, q);\
116 	return -1; }
117 #define ERROR_FLOOR(res, i, pow) \
118 		(res % pow) || 						/* check if not aligned */ \
119 		((res / pow) != (i / pow))  		/* check if correct alignment */
120 #define ERROR_CEIL(res, i, pow) \
121 		(res % pow) ||						/* check if not aligned */ \
122 			((i % pow) == 0 ?				/* check if ceiling is invoked */ \
123 			val / pow != i / pow :			/* if aligned */ \
124 			val / pow != (i / pow) + 1)		/* if not aligned, hence +1 */
125 
126 	uint32_t i, p, val;
127 	uint64_t j, q;
128 
129 	for (i = 1, p = 1; i <= MAX_NUM; i ++) {
130 		if (rte_align32pow2(i) != p)
131 			FAIL_ALIGN("rte_align32pow2", i, p);
132 		if (i == p)
133 			p <<= 1;
134 	}
135 
136 	for (i = 1, p = 1; i <= MAX_NUM; i++) {
137 		if (rte_align32prevpow2(i) != p)
138 			FAIL_ALIGN("rte_align32prevpow2", i, p);
139 		if (rte_is_power_of_2(i + 1))
140 			p = i + 1;
141 	}
142 
143 	for (j = 1, q = 1; j <= MAX_NUM ; j++) {
144 		if (rte_align64pow2(j) != q)
145 			FAIL_ALIGN64("rte_align64pow2", j, q);
146 		if (j == q)
147 			q <<= 1;
148 	}
149 
150 	for (j = 1, q = 1; j <= MAX_NUM ; j++) {
151 		if (rte_align64prevpow2(j) != q)
152 			FAIL_ALIGN64("rte_align64prevpow2", j, q);
153 		if (rte_is_power_of_2(j + 1))
154 			q = j + 1;
155 	}
156 
157 	for (p = 2; p <= MAX_NUM; p <<= 1) {
158 
159 		if (!rte_is_power_of_2(p))
160 			FAIL("rte_is_power_of_2");
161 
162 		for (i = 1; i <= MAX_NUM; i++) {
163 			/* align floor */
164 			if (RTE_ALIGN_FLOOR((uintptr_t)i, p) % p)
165 				FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p);
166 
167 			val = RTE_PTR_ALIGN_FLOOR((uintptr_t) i, p);
168 			if (ERROR_FLOOR(val, i, p))
169 				FAIL_ALIGN("RTE_PTR_ALIGN_FLOOR", i, p);
170 
171 			val = RTE_ALIGN_FLOOR(i, p);
172 			if (ERROR_FLOOR(val, i, p))
173 				FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p);
174 
175 			/* align ceiling */
176 			val = RTE_PTR_ALIGN((uintptr_t) i, p);
177 			if (ERROR_CEIL(val, i, p))
178 				FAIL_ALIGN("RTE_PTR_ALIGN", i, p);
179 
180 			val = RTE_ALIGN(i, p);
181 			if (ERROR_CEIL(val, i, p))
182 				FAIL_ALIGN("RTE_ALIGN", i, p);
183 
184 			val = RTE_ALIGN_CEIL(i, p);
185 			if (ERROR_CEIL(val, i, p))
186 				FAIL_ALIGN("RTE_ALIGN_CEIL", i, p);
187 
188 			val = RTE_PTR_ALIGN_CEIL((uintptr_t)i, p);
189 			if (ERROR_CEIL(val, i, p))
190 				FAIL_ALIGN("RTE_PTR_ALIGN_CEIL", i, p);
191 
192 			/* by this point we know that val is aligned to p */
193 			if (!rte_is_aligned((void*)(uintptr_t) val, p))
194 				FAIL("rte_is_aligned");
195 		}
196 	}
197 
198 	for (p = 1; p <= MAX_NUM / 2; p++) {
199 		for (i = 1; i <= MAX_NUM / 2; i++) {
200 			val = RTE_ALIGN_MUL_CEIL(i, p);
201 			if (val % p != 0 || val < i)
202 				FAIL_ALIGN("RTE_ALIGN_MUL_CEIL", i, p);
203 			val = RTE_ALIGN_MUL_FLOOR(i, p);
204 			if (val % p != 0 || val > i)
205 				FAIL_ALIGN("RTE_ALIGN_MUL_FLOOR", i, p);
206 			val = RTE_ALIGN_MUL_NEAR(i, p);
207 			if (val % p != 0 || ((val != RTE_ALIGN_MUL_CEIL(i, p))
208 				& (val != RTE_ALIGN_MUL_FLOOR(i, p))))
209 				FAIL_ALIGN("RTE_ALIGN_MUL_NEAR", i, p);
210 		}
211 	}
212 
213 	return 0;
214 }
215 
216 static int
217 test_log2(void)
218 {
219 	uint32_t i, base, compare;
220 	const uint32_t max = 0x10000;
221 	const uint32_t step = 1;
222 
223 	compare = rte_log2_u32(0);
224 	if (compare != 0) {
225 		printf("Wrong rte_log2_u32(0) val %x, expected 0\n", compare);
226 		return TEST_FAILED;
227 	}
228 
229 	compare = rte_log2_u64(0);
230 	if (compare != 0) {
231 		printf("Wrong rte_log2_u64(0) val %x, expected 0\n", compare);
232 		return TEST_FAILED;
233 	}
234 
235 	for (i = 1; i < max; i = i + step) {
236 		uint64_t i64;
237 
238 		/* extend range for 64-bit */
239 		i64 = (uint64_t)i << 32;
240 		base = (uint32_t)ceilf(log2(i64));
241 		compare = rte_log2_u64(i64);
242 		if (base != compare) {
243 			printf("Wrong rte_log2_u64(%" PRIx64 ") val %x, expected %x\n",
244 				i64, compare, base);
245 			return TEST_FAILED;
246 		}
247 
248 		base = (uint32_t)ceilf(log2((uint32_t)i));
249 		compare = rte_log2_u32((uint32_t)i);
250 		if (base != compare) {
251 			printf("Wrong rte_log2_u32(%x) val %x, expected %x\n",
252 				i, compare, base);
253 			return TEST_FAILED;
254 		}
255 		compare = rte_log2_u64((uint64_t)i);
256 		if (base != compare) {
257 			printf("Wrong rte_log2_u64(%x) val %x, expected %x\n",
258 				i, compare, base);
259 			return TEST_FAILED;
260 		}
261 	}
262 	return 0;
263 }
264 
265 static int
266 test_fls(void)
267 {
268 	struct fls_test_vector {
269 		uint32_t arg;
270 		int rc;
271 	};
272 	int expected, rc;
273 	uint32_t i, arg;
274 
275 	const struct fls_test_vector test[] = {
276 		{0x0, 0},
277 		{0x1, 1},
278 		{0x4000, 15},
279 		{0x80000000, 32},
280 	};
281 
282 	for (i = 0; i < RTE_DIM(test); i++) {
283 		uint64_t arg64;
284 
285 		arg = test[i].arg;
286 		rc = rte_fls_u32(arg);
287 		expected = test[i].rc;
288 		if (rc != expected) {
289 			printf("Wrong rte_fls_u32(0x%x) rc=%d, expected=%d\n",
290 				arg, rc, expected);
291 			return TEST_FAILED;
292 		}
293 		/* 64-bit version */
294 		arg = test[i].arg;
295 		rc = rte_fls_u64(arg);
296 		expected = test[i].rc;
297 		if (rc != expected) {
298 			printf("Wrong rte_fls_u64(0x%x) rc=%d, expected=%d\n",
299 				arg, rc, expected);
300 			return TEST_FAILED;
301 		}
302 		/* 64-bit version shifted by 32 bits */
303 		arg64 = (uint64_t)test[i].arg << 32;
304 		rc = rte_fls_u64(arg64);
305 		/* don't shift zero */
306 		expected = test[i].rc == 0 ? 0 : test[i].rc + 32;
307 		if (rc != expected) {
308 			printf("Wrong rte_fls_u64(0x%" PRIx64 ") rc=%d, expected=%d\n",
309 				arg64, rc, expected);
310 			return TEST_FAILED;
311 		}
312 	}
313 
314 	return 0;
315 }
316 
317 static int
318 test_common(void)
319 {
320 	int ret = 0;
321 	ret |= test_align();
322 	ret |= test_macros(0);
323 	ret |= test_misc();
324 	ret |= test_bsf();
325 	ret |= test_log2();
326 	ret |= test_fls();
327 
328 	return ret;
329 }
330 
331 REGISTER_TEST_COMMAND(common_autotest, test_common);
332