xref: /dpdk/app/test/test_ring.c (revision 9e991f217fc8719e38a812dc280dba5f84db9f59)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #include <errno.h>
12 #include <sys/queue.h>
13 
14 #include <rte_common.h>
15 #include <rte_log.h>
16 #include <rte_memory.h>
17 #include <rte_launch.h>
18 #include <rte_cycles.h>
19 #include <rte_eal.h>
20 #include <rte_per_lcore.h>
21 #include <rte_lcore.h>
22 #include <rte_atomic.h>
23 #include <rte_branch_prediction.h>
24 #include <rte_malloc.h>
25 #include <rte_ring.h>
26 #include <rte_ring_elem.h>
27 #include <rte_random.h>
28 #include <rte_errno.h>
29 #include <rte_hexdump.h>
30 
31 #include "test.h"
32 #include "test_ring.h"
33 
34 /*
35  * Ring
36  * ====
37  *
38  * #. Functional tests. Tests single/bulk/burst, default/SPSC/MPMC,
39  *    legacy/custom element size (4B, 8B, 16B, 20B) APIs.
40  *    Some tests incorporate unaligned addresses for objects.
41  *    The enqueued/dequeued data is validated for correctness.
42  *
43  * #. Performance tests are in test_ring_perf.c
44  */
45 
46 #define RING_SIZE 4096
47 #define MAX_BULK 32
48 
49 #define	TEST_RING_VERIFY(exp)						\
50 	if (!(exp)) {							\
51 		printf("error at %s:%d\tcondition " #exp " failed\n",	\
52 		    __func__, __LINE__);				\
53 		rte_ring_dump(stdout, r);				\
54 		return -1;						\
55 	}
56 
57 #define	TEST_RING_FULL_EMTPY_ITER	8
58 
59 static const int esize[] = {-1, 4, 8, 16, 20};
60 
61 static void**
62 test_ring_inc_ptr(void **obj, int esize, unsigned int n)
63 {
64 	/* Legacy queue APIs? */
65 	if ((esize) == -1)
66 		return ((void **)obj) + n;
67 	else
68 		return (void **)(((uint32_t *)obj) +
69 					(n * esize / sizeof(uint32_t)));
70 }
71 
72 static void
73 test_ring_mem_init(void *obj, unsigned int count, int esize)
74 {
75 	unsigned int i;
76 
77 	/* Legacy queue APIs? */
78 	if (esize == -1)
79 		for (i = 0; i < count; i++)
80 			((void **)obj)[i] = (void *)(unsigned long)i;
81 	else
82 		for (i = 0; i < (count * esize / sizeof(uint32_t)); i++)
83 			((uint32_t *)obj)[i] = i;
84 }
85 
86 static void
87 test_ring_print_test_string(const char *istr, unsigned int api_type, int esize)
88 {
89 	printf("\n%s: ", istr);
90 
91 	if (esize == -1)
92 		printf("legacy APIs: ");
93 	else
94 		printf("elem APIs: element size %dB ", esize);
95 
96 	if (api_type == TEST_RING_IGNORE_API_TYPE)
97 		return;
98 
99 	if (api_type & TEST_RING_THREAD_DEF)
100 		printf(": default enqueue/dequeue: ");
101 	else if (api_type & TEST_RING_THREAD_SPSC)
102 		printf(": SP/SC: ");
103 	else if (api_type & TEST_RING_THREAD_MPMC)
104 		printf(": MP/MC: ");
105 
106 	if (api_type & TEST_RING_ELEM_SINGLE)
107 		printf("single\n");
108 	else if (api_type & TEST_RING_ELEM_BULK)
109 		printf("bulk\n");
110 	else if (api_type & TEST_RING_ELEM_BURST)
111 		printf("burst\n");
112 }
113 
114 /*
115  * Various negative test cases.
116  */
117 static int
118 test_ring_negative_tests(void)
119 {
120 	struct rte_ring *rp = NULL;
121 	struct rte_ring *rt = NULL;
122 	unsigned int i;
123 
124 	/* Test with esize not a multiple of 4 */
125 	rp = test_ring_create("test_bad_element_size", 23,
126 				RING_SIZE + 1, SOCKET_ID_ANY, 0);
127 	if (rp != NULL) {
128 		printf("Test failed to detect invalid element size\n");
129 		goto test_fail;
130 	}
131 
132 
133 	for (i = 0; i < RTE_DIM(esize); i++) {
134 		/* Test if ring size is not power of 2 */
135 		rp = test_ring_create("test_bad_ring_size", esize[i],
136 					RING_SIZE + 1, SOCKET_ID_ANY, 0);
137 		if (rp != NULL) {
138 			printf("Test failed to detect odd count\n");
139 			goto test_fail;
140 		}
141 
142 		/* Test if ring size is exceeding the limit */
143 		rp = test_ring_create("test_bad_ring_size", esize[i],
144 					RTE_RING_SZ_MASK + 1, SOCKET_ID_ANY, 0);
145 		if (rp != NULL) {
146 			printf("Test failed to detect limits\n");
147 			goto test_fail;
148 		}
149 
150 		/* Tests if lookup returns NULL on non-existing ring */
151 		rp = rte_ring_lookup("ring_not_found");
152 		if (rp != NULL && rte_errno != ENOENT) {
153 			printf("Test failed to detect NULL ring lookup\n");
154 			goto test_fail;
155 		}
156 
157 		/* Test to if a non-power of 2 count causes the create
158 		 * function to fail correctly
159 		 */
160 		rp = test_ring_create("test_ring_count", esize[i], 4097,
161 					SOCKET_ID_ANY, 0);
162 		if (rp != NULL)
163 			goto test_fail;
164 
165 		rp = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
166 					SOCKET_ID_ANY,
167 					RING_F_SP_ENQ | RING_F_SC_DEQ);
168 		if (rp == NULL) {
169 			printf("test_ring_negative fail to create ring\n");
170 			goto test_fail;
171 		}
172 
173 		if (rte_ring_lookup("test_ring_negative") != rp)
174 			goto test_fail;
175 
176 		if (rte_ring_empty(rp) != 1) {
177 			printf("test_ring_nagative ring is not empty but it should be\n");
178 			goto test_fail;
179 		}
180 
181 		/* Tests if it would always fail to create ring with an used
182 		 * ring name.
183 		 */
184 		rt = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
185 					SOCKET_ID_ANY, 0);
186 		if (rt != NULL)
187 			goto test_fail;
188 
189 		rte_ring_free(rp);
190 		rp = NULL;
191 	}
192 
193 	return 0;
194 
195 test_fail:
196 
197 	rte_ring_free(rp);
198 	return -1;
199 }
200 
201 /*
202  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
203  * Random number of elements are enqueued and dequeued.
204  */
205 static int
206 test_ring_burst_bulk_tests1(unsigned int api_type)
207 {
208 	struct rte_ring *r;
209 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
210 	int ret;
211 	unsigned int i, j;
212 	int rand;
213 	const unsigned int rsz = RING_SIZE - 1;
214 
215 	for (i = 0; i < RTE_DIM(esize); i++) {
216 		test_ring_print_test_string("Test standard ring", api_type,
217 						esize[i]);
218 
219 		/* Create the ring */
220 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
221 					RING_SIZE, SOCKET_ID_ANY, 0);
222 
223 		/* alloc dummy object pointers */
224 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
225 		if (src == NULL)
226 			goto fail;
227 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
228 		cur_src = src;
229 
230 		/* alloc some room for copied objects */
231 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
232 		if (dst == NULL)
233 			goto fail;
234 		cur_dst = dst;
235 
236 		printf("Random full/empty test\n");
237 
238 		for (j = 0; j != TEST_RING_FULL_EMTPY_ITER; j++) {
239 			/* random shift in the ring */
240 			rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
241 			printf("%s: iteration %u, random shift: %u;\n",
242 			    __func__, i, rand);
243 			ret = test_ring_enqueue(r, cur_src, esize[i], rand,
244 							api_type);
245 			TEST_RING_VERIFY(ret != 0);
246 
247 			ret = test_ring_dequeue(r, cur_dst, esize[i], rand,
248 							api_type);
249 			TEST_RING_VERIFY(ret == rand);
250 
251 			/* fill the ring */
252 			ret = test_ring_enqueue(r, cur_src, esize[i], rsz,
253 							api_type);
254 			TEST_RING_VERIFY(ret != 0);
255 
256 			TEST_RING_VERIFY(rte_ring_free_count(r) == 0);
257 			TEST_RING_VERIFY(rsz == rte_ring_count(r));
258 			TEST_RING_VERIFY(rte_ring_full(r));
259 			TEST_RING_VERIFY(rte_ring_empty(r) == 0);
260 
261 			/* empty the ring */
262 			ret = test_ring_dequeue(r, cur_dst, esize[i], rsz,
263 							api_type);
264 			TEST_RING_VERIFY(ret == (int)rsz);
265 			TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
266 			TEST_RING_VERIFY(rte_ring_count(r) == 0);
267 			TEST_RING_VERIFY(rte_ring_full(r) == 0);
268 			TEST_RING_VERIFY(rte_ring_empty(r));
269 
270 			/* check data */
271 			TEST_RING_VERIFY(memcmp(src, dst, rsz) == 0);
272 		}
273 
274 		/* Free memory before test completed */
275 		rte_ring_free(r);
276 		rte_free(src);
277 		rte_free(dst);
278 		r = NULL;
279 		src = NULL;
280 		dst = NULL;
281 	}
282 
283 	return 0;
284 fail:
285 	rte_ring_free(r);
286 	rte_free(src);
287 	rte_free(dst);
288 	return -1;
289 }
290 
291 /*
292  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
293  * Sequence of simple enqueues/dequeues and validate the enqueued and
294  * dequeued data.
295  */
296 static int
297 test_ring_burst_bulk_tests2(unsigned int api_type)
298 {
299 	struct rte_ring *r;
300 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
301 	int ret;
302 	unsigned int i;
303 
304 	for (i = 0; i < RTE_DIM(esize); i++) {
305 		test_ring_print_test_string("Test standard ring", api_type,
306 						esize[i]);
307 
308 		/* Create the ring */
309 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
310 					RING_SIZE, SOCKET_ID_ANY, 0);
311 
312 		/* alloc dummy object pointers */
313 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
314 		if (src == NULL)
315 			goto fail;
316 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
317 		cur_src = src;
318 
319 		/* alloc some room for copied objects */
320 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
321 		if (dst == NULL)
322 			goto fail;
323 		cur_dst = dst;
324 
325 		printf("enqueue 1 obj\n");
326 		ret = test_ring_enqueue(r, cur_src, esize[i], 1, api_type);
327 		if (ret != 1)
328 			goto fail;
329 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
330 
331 		printf("enqueue 2 objs\n");
332 		ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type);
333 		if (ret != 2)
334 			goto fail;
335 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
336 
337 		printf("enqueue MAX_BULK objs\n");
338 		ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
339 						api_type);
340 		if (ret != MAX_BULK)
341 			goto fail;
342 		cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK);
343 
344 		printf("dequeue 1 obj\n");
345 		ret = test_ring_dequeue(r, cur_dst, esize[i], 1, api_type);
346 		if (ret != 1)
347 			goto fail;
348 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
349 
350 		printf("dequeue 2 objs\n");
351 		ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type);
352 		if (ret != 2)
353 			goto fail;
354 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
355 
356 		printf("dequeue MAX_BULK objs\n");
357 		ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
358 						api_type);
359 		if (ret != MAX_BULK)
360 			goto fail;
361 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK);
362 
363 		/* check data */
364 		if (memcmp(src, dst, cur_dst - dst)) {
365 			rte_hexdump(stdout, "src", src, cur_src - src);
366 			rte_hexdump(stdout, "dst", dst, cur_dst - dst);
367 			printf("data after dequeue is not the same\n");
368 			goto fail;
369 		}
370 
371 		/* Free memory before test completed */
372 		rte_ring_free(r);
373 		rte_free(src);
374 		rte_free(dst);
375 		r = NULL;
376 		src = NULL;
377 		dst = NULL;
378 	}
379 
380 	return 0;
381 fail:
382 	rte_ring_free(r);
383 	rte_free(src);
384 	rte_free(dst);
385 	return -1;
386 }
387 
388 /*
389  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
390  * Enqueue and dequeue to cover the entire ring length.
391  */
392 static int
393 test_ring_burst_bulk_tests3(unsigned int api_type)
394 {
395 	struct rte_ring *r;
396 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
397 	int ret;
398 	unsigned int i, j;
399 
400 	for (i = 0; i < RTE_DIM(esize); i++) {
401 		test_ring_print_test_string("Test standard ring", api_type,
402 						esize[i]);
403 
404 		/* Create the ring */
405 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
406 					RING_SIZE, SOCKET_ID_ANY, 0);
407 
408 		/* alloc dummy object pointers */
409 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
410 		if (src == NULL)
411 			goto fail;
412 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
413 		cur_src = src;
414 
415 		/* alloc some room for copied objects */
416 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
417 		if (dst == NULL)
418 			goto fail;
419 		cur_dst = dst;
420 
421 		printf("fill and empty the ring\n");
422 		for (j = 0; j < RING_SIZE / MAX_BULK; j++) {
423 			ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
424 							api_type);
425 			if (ret != MAX_BULK)
426 				goto fail;
427 			cur_src = test_ring_inc_ptr(cur_src, esize[i],
428 								MAX_BULK);
429 
430 			ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
431 							api_type);
432 			if (ret != MAX_BULK)
433 				goto fail;
434 			cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
435 								MAX_BULK);
436 		}
437 
438 		/* check data */
439 		if (memcmp(src, dst, cur_dst - dst)) {
440 			rte_hexdump(stdout, "src", src, cur_src - src);
441 			rte_hexdump(stdout, "dst", dst, cur_dst - dst);
442 			printf("data after dequeue is not the same\n");
443 			goto fail;
444 		}
445 
446 		/* Free memory before test completed */
447 		rte_ring_free(r);
448 		rte_free(src);
449 		rte_free(dst);
450 		r = NULL;
451 		src = NULL;
452 		dst = NULL;
453 	}
454 
455 	return 0;
456 fail:
457 	rte_ring_free(r);
458 	rte_free(src);
459 	rte_free(dst);
460 	return -1;
461 }
462 
463 /*
464  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
465  * Enqueue till the ring is full and dequeue till the ring becomes empty.
466  */
467 static int
468 test_ring_burst_bulk_tests4(unsigned int api_type)
469 {
470 	struct rte_ring *r;
471 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
472 	int ret;
473 	unsigned int i, j;
474 	unsigned int num_elems;
475 
476 	for (i = 0; i < RTE_DIM(esize); i++) {
477 		test_ring_print_test_string("Test standard ring", api_type,
478 						esize[i]);
479 
480 		/* Create the ring */
481 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
482 					RING_SIZE, SOCKET_ID_ANY, 0);
483 
484 		/* alloc dummy object pointers */
485 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
486 		if (src == NULL)
487 			goto fail;
488 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
489 		cur_src = src;
490 
491 		/* alloc some room for copied objects */
492 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
493 		if (dst == NULL)
494 			goto fail;
495 		cur_dst = dst;
496 
497 		printf("Test enqueue without enough memory space\n");
498 		for (j = 0; j < (RING_SIZE/MAX_BULK - 1); j++) {
499 			ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
500 							api_type);
501 			if (ret != MAX_BULK)
502 				goto fail;
503 			cur_src = test_ring_inc_ptr(cur_src, esize[i],
504 								MAX_BULK);
505 		}
506 
507 		printf("Enqueue 2 objects, free entries = MAX_BULK - 2\n");
508 		ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type);
509 		if (ret != 2)
510 			goto fail;
511 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
512 
513 		printf("Enqueue the remaining entries = MAX_BULK - 3\n");
514 		/* Bulk APIs enqueue exact number of elements */
515 		if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
516 			num_elems = MAX_BULK - 3;
517 		else
518 			num_elems = MAX_BULK;
519 		/* Always one free entry left */
520 		ret = test_ring_enqueue(r, cur_src, esize[i], num_elems,
521 						api_type);
522 		if (ret != MAX_BULK - 3)
523 			goto fail;
524 		cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK - 3);
525 
526 		printf("Test if ring is full\n");
527 		if (rte_ring_full(r) != 1)
528 			goto fail;
529 
530 		printf("Test enqueue for a full entry\n");
531 		ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
532 						api_type);
533 		if (ret != 0)
534 			goto fail;
535 
536 		printf("Test dequeue without enough objects\n");
537 		for (j = 0; j < RING_SIZE / MAX_BULK - 1; j++) {
538 			ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
539 							api_type);
540 			if (ret != MAX_BULK)
541 				goto fail;
542 			cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
543 								MAX_BULK);
544 		}
545 
546 		/* Available memory space for the exact MAX_BULK entries */
547 		ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type);
548 		if (ret != 2)
549 			goto fail;
550 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
551 
552 		/* Bulk APIs enqueue exact number of elements */
553 		if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
554 			num_elems = MAX_BULK - 3;
555 		else
556 			num_elems = MAX_BULK;
557 		ret = test_ring_dequeue(r, cur_dst, esize[i], num_elems,
558 						api_type);
559 		if (ret != MAX_BULK - 3)
560 			goto fail;
561 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK - 3);
562 
563 		printf("Test if ring is empty\n");
564 		/* Check if ring is empty */
565 		if (rte_ring_empty(r) != 1)
566 			goto fail;
567 
568 		/* check data */
569 		if (memcmp(src, dst, cur_dst - dst)) {
570 			rte_hexdump(stdout, "src", src, cur_src - src);
571 			rte_hexdump(stdout, "dst", dst, cur_dst - dst);
572 			printf("data after dequeue is not the same\n");
573 			goto fail;
574 		}
575 
576 		/* Free memory before test completed */
577 		rte_ring_free(r);
578 		rte_free(src);
579 		rte_free(dst);
580 		r = NULL;
581 		src = NULL;
582 		dst = NULL;
583 	}
584 
585 	return 0;
586 fail:
587 	rte_ring_free(r);
588 	rte_free(src);
589 	rte_free(dst);
590 	return -1;
591 }
592 
593 /*
594  * Test default, single element, bulk and burst APIs
595  */
596 static int
597 test_ring_basic_ex(void)
598 {
599 	int ret = -1;
600 	unsigned int i, j;
601 	struct rte_ring *rp = NULL;
602 	void *obj = NULL;
603 
604 	for (i = 0; i < RTE_DIM(esize); i++) {
605 		obj = test_ring_calloc(RING_SIZE, esize[i]);
606 		if (obj == NULL) {
607 			printf("%s: failed to alloc memory\n", __func__);
608 			goto fail_test;
609 		}
610 
611 		rp = test_ring_create("test_ring_basic_ex", esize[i], RING_SIZE,
612 					SOCKET_ID_ANY,
613 					RING_F_SP_ENQ | RING_F_SC_DEQ);
614 		if (rp == NULL) {
615 			printf("%s: failed to create ring\n", __func__);
616 			goto fail_test;
617 		}
618 
619 		if (rte_ring_lookup("test_ring_basic_ex") != rp) {
620 			printf("%s: failed to find ring\n", __func__);
621 			goto fail_test;
622 		}
623 
624 		if (rte_ring_empty(rp) != 1) {
625 			printf("%s: ring is not empty but it should be\n",
626 				__func__);
627 			goto fail_test;
628 		}
629 
630 		printf("%u ring entries are now free\n",
631 			rte_ring_free_count(rp));
632 
633 		for (j = 0; j < RING_SIZE; j++) {
634 			test_ring_enqueue(rp, obj, esize[i], 1,
635 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
636 		}
637 
638 		if (rte_ring_full(rp) != 1) {
639 			printf("%s: ring is not full but it should be\n",
640 				__func__);
641 			goto fail_test;
642 		}
643 
644 		for (j = 0; j < RING_SIZE; j++) {
645 			test_ring_dequeue(rp, obj, esize[i], 1,
646 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
647 		}
648 
649 		if (rte_ring_empty(rp) != 1) {
650 			printf("%s: ring is not empty but it should be\n",
651 				__func__);
652 			goto fail_test;
653 		}
654 
655 		/* Following tests use the configured flags to decide
656 		 * SP/SC or MP/MC.
657 		 */
658 		/* Covering the ring burst operation */
659 		ret = test_ring_enqueue(rp, obj, esize[i], 2,
660 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
661 		if (ret != 2) {
662 			printf("%s: rte_ring_enqueue_burst fails\n", __func__);
663 			goto fail_test;
664 		}
665 
666 		ret = test_ring_dequeue(rp, obj, esize[i], 2,
667 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
668 		if (ret != 2) {
669 			printf("%s: rte_ring_dequeue_burst fails\n", __func__);
670 			goto fail_test;
671 		}
672 
673 		/* Covering the ring bulk operation */
674 		ret = test_ring_enqueue(rp, obj, esize[i], 2,
675 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
676 		if (ret != 2) {
677 			printf("%s: rte_ring_enqueue_bulk fails\n", __func__);
678 			goto fail_test;
679 		}
680 
681 		ret = test_ring_dequeue(rp, obj, esize[i], 2,
682 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
683 		if (ret != 2) {
684 			printf("%s: rte_ring_dequeue_bulk fails\n", __func__);
685 			goto fail_test;
686 		}
687 
688 		rte_ring_free(rp);
689 		rte_free(obj);
690 		rp = NULL;
691 		obj = NULL;
692 	}
693 
694 	return 0;
695 
696 fail_test:
697 	rte_ring_free(rp);
698 	if (obj != NULL)
699 		rte_free(obj);
700 
701 	return -1;
702 }
703 
704 /*
705  * Basic test cases with exact size ring.
706  */
707 static int
708 test_ring_with_exact_size(void)
709 {
710 	struct rte_ring *std_r = NULL, *exact_sz_r = NULL;
711 	void *obj_orig;
712 	void *obj;
713 	const unsigned int ring_sz = 16;
714 	unsigned int i, j;
715 	int ret = -1;
716 
717 	for (i = 0; i < RTE_DIM(esize); i++) {
718 		test_ring_print_test_string("Test exact size ring",
719 				TEST_RING_IGNORE_API_TYPE,
720 				esize[i]);
721 
722 		/* alloc object pointers. Allocate one extra object
723 		 * and create an unaligned address.
724 		 */
725 		obj_orig = test_ring_calloc(17, esize[i]);
726 		if (obj_orig == NULL)
727 			goto test_fail;
728 		obj = ((char *)obj_orig) + 1;
729 
730 		std_r = test_ring_create("std", esize[i], ring_sz,
731 					rte_socket_id(),
732 					RING_F_SP_ENQ | RING_F_SC_DEQ);
733 		if (std_r == NULL) {
734 			printf("%s: error, can't create std ring\n", __func__);
735 			goto test_fail;
736 		}
737 		exact_sz_r = test_ring_create("exact sz", esize[i], ring_sz,
738 				rte_socket_id(),
739 				RING_F_SP_ENQ | RING_F_SC_DEQ |
740 				RING_F_EXACT_SZ);
741 		if (exact_sz_r == NULL) {
742 			printf("%s: error, can't create exact size ring\n",
743 					__func__);
744 			goto test_fail;
745 		}
746 
747 		/*
748 		 * Check that the exact size ring is bigger than the
749 		 * standard ring
750 		 */
751 		if (rte_ring_get_size(std_r) >= rte_ring_get_size(exact_sz_r)) {
752 			printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n",
753 					__func__,
754 					rte_ring_get_size(std_r),
755 					rte_ring_get_size(exact_sz_r));
756 			goto test_fail;
757 		}
758 		/*
759 		 * check that the exact_sz_ring can hold one more element
760 		 * than the standard ring. (16 vs 15 elements)
761 		 */
762 		for (j = 0; j < ring_sz - 1; j++) {
763 			test_ring_enqueue(std_r, obj, esize[i], 1,
764 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
765 			test_ring_enqueue(exact_sz_r, obj, esize[i], 1,
766 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
767 		}
768 		ret = test_ring_enqueue(std_r, obj, esize[i], 1,
769 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
770 		if (ret != -ENOBUFS) {
771 			printf("%s: error, unexpected successful enqueue\n",
772 				__func__);
773 			goto test_fail;
774 		}
775 		ret = test_ring_enqueue(exact_sz_r, obj, esize[i], 1,
776 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
777 		if (ret == -ENOBUFS) {
778 			printf("%s: error, enqueue failed\n", __func__);
779 			goto test_fail;
780 		}
781 
782 		/* check that dequeue returns the expected number of elements */
783 		ret = test_ring_dequeue(exact_sz_r, obj, esize[i], ring_sz,
784 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
785 		if (ret != (int)ring_sz) {
786 			printf("%s: error, failed to dequeue expected nb of elements\n",
787 				__func__);
788 			goto test_fail;
789 		}
790 
791 		/* check that the capacity function returns expected value */
792 		if (rte_ring_get_capacity(exact_sz_r) != ring_sz) {
793 			printf("%s: error, incorrect ring capacity reported\n",
794 					__func__);
795 			goto test_fail;
796 		}
797 
798 		rte_free(obj_orig);
799 		rte_ring_free(std_r);
800 		rte_ring_free(exact_sz_r);
801 		obj_orig = NULL;
802 		std_r = NULL;
803 		exact_sz_r = NULL;
804 	}
805 
806 	return 0;
807 
808 test_fail:
809 	rte_free(obj_orig);
810 	rte_ring_free(std_r);
811 	rte_ring_free(exact_sz_r);
812 	return -1;
813 }
814 
815 static int
816 test_ring(void)
817 {
818 	unsigned int i, j;
819 
820 	/* Negative test cases */
821 	if (test_ring_negative_tests() < 0)
822 		goto test_fail;
823 
824 	/* Some basic operations */
825 	if (test_ring_basic_ex() < 0)
826 		goto test_fail;
827 
828 	if (test_ring_with_exact_size() < 0)
829 		goto test_fail;
830 
831 	/* Burst and bulk operations with sp/sc, mp/mc and default.
832 	 * The test cases are split into smaller test cases to
833 	 * help clang compile faster.
834 	 */
835 	for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
836 		for (i = TEST_RING_THREAD_DEF;
837 					i <= TEST_RING_THREAD_MPMC; i <<= 1)
838 			if (test_ring_burst_bulk_tests1(i | j) < 0)
839 				goto test_fail;
840 
841 	for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
842 		for (i = TEST_RING_THREAD_DEF;
843 					i <= TEST_RING_THREAD_MPMC; i <<= 1)
844 			if (test_ring_burst_bulk_tests2(i | j) < 0)
845 				goto test_fail;
846 
847 	for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
848 		for (i = TEST_RING_THREAD_DEF;
849 					i <= TEST_RING_THREAD_MPMC; i <<= 1)
850 			if (test_ring_burst_bulk_tests3(i | j) < 0)
851 				goto test_fail;
852 
853 	for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
854 		for (i = TEST_RING_THREAD_DEF;
855 					i <= TEST_RING_THREAD_MPMC; i <<= 1)
856 			if (test_ring_burst_bulk_tests4(i | j) < 0)
857 				goto test_fail;
858 
859 	/* dump the ring status */
860 	rte_ring_list_dump(stdout);
861 
862 	return 0;
863 
864 test_fail:
865 
866 	return -1;
867 }
868 
869 REGISTER_TEST_COMMAND(ring_autotest, test_ring);
870