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