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