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