New upstream version 18.02
[deb_dpdk.git] / test / test / test_ring.c
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);