ring: return free space when enqueuing
[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) == 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) == rsz);
133                 TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
134                 TEST_RING_VERIFY(0 == rte_ring_count(r));
135                 TEST_RING_VERIFY(0 == rte_ring_full(r));
136                 TEST_RING_VERIFY(rte_ring_empty(r));
137
138                 /* check data */
139                 TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
140                 rte_ring_dump(stdout, r);
141         }
142         return 0;
143 }
144
145 static int
146 test_ring_basic(void)
147 {
148         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
149         int ret;
150         unsigned i, num_elems;
151
152         /* alloc dummy object pointers */
153         src = malloc(RING_SIZE*2*sizeof(void *));
154         if (src == NULL)
155                 goto fail;
156
157         for (i = 0; i < RING_SIZE*2 ; i++) {
158                 src[i] = (void *)(unsigned long)i;
159         }
160         cur_src = src;
161
162         /* alloc some room for copied objects */
163         dst = malloc(RING_SIZE*2*sizeof(void *));
164         if (dst == NULL)
165                 goto fail;
166
167         memset(dst, 0, RING_SIZE*2*sizeof(void *));
168         cur_dst = dst;
169
170         printf("enqueue 1 obj\n");
171         ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1, NULL);
172         cur_src += 1;
173         if (ret == 0)
174                 goto fail;
175
176         printf("enqueue 2 objs\n");
177         ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2, NULL);
178         cur_src += 2;
179         if (ret == 0)
180                 goto fail;
181
182         printf("enqueue MAX_BULK objs\n");
183         ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK, NULL);
184         cur_src += MAX_BULK;
185         if (ret == 0)
186                 goto fail;
187
188         printf("dequeue 1 obj\n");
189         ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
190         cur_dst += 1;
191         if (ret == 0)
192                 goto fail;
193
194         printf("dequeue 2 objs\n");
195         ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
196         cur_dst += 2;
197         if (ret == 0)
198                 goto fail;
199
200         printf("dequeue MAX_BULK objs\n");
201         ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
202         cur_dst += MAX_BULK;
203         if (ret == 0)
204                 goto fail;
205
206         /* check data */
207         if (memcmp(src, dst, cur_dst - dst)) {
208                 rte_hexdump(stdout, "src", src, cur_src - src);
209                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
210                 printf("data after dequeue is not the same\n");
211                 goto fail;
212         }
213         cur_src = src;
214         cur_dst = dst;
215
216         printf("enqueue 1 obj\n");
217         ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1, NULL);
218         cur_src += 1;
219         if (ret == 0)
220                 goto fail;
221
222         printf("enqueue 2 objs\n");
223         ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2, NULL);
224         cur_src += 2;
225         if (ret == 0)
226                 goto fail;
227
228         printf("enqueue MAX_BULK objs\n");
229         ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK, NULL);
230         cur_src += MAX_BULK;
231         if (ret == 0)
232                 goto fail;
233
234         printf("dequeue 1 obj\n");
235         ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
236         cur_dst += 1;
237         if (ret == 0)
238                 goto fail;
239
240         printf("dequeue 2 objs\n");
241         ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
242         cur_dst += 2;
243         if (ret == 0)
244                 goto fail;
245
246         printf("dequeue MAX_BULK objs\n");
247         ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
248         cur_dst += MAX_BULK;
249         if (ret == 0)
250                 goto fail;
251
252         /* check data */
253         if (memcmp(src, dst, cur_dst - dst)) {
254                 rte_hexdump(stdout, "src", src, cur_src - src);
255                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
256                 printf("data after dequeue is not the same\n");
257                 goto fail;
258         }
259         cur_src = src;
260         cur_dst = dst;
261
262         printf("fill and empty the ring\n");
263         for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
264                 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK, NULL);
265                 cur_src += MAX_BULK;
266                 if (ret == 0)
267                         goto fail;
268                 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
269                 cur_dst += MAX_BULK;
270                 if (ret == 0)
271                         goto fail;
272         }
273
274         /* check data */
275         if (memcmp(src, dst, cur_dst - dst)) {
276                 rte_hexdump(stdout, "src", src, cur_src - src);
277                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
278                 printf("data after dequeue is not the same\n");
279                 goto fail;
280         }
281
282         if (test_ring_basic_full_empty(src, dst) != 0)
283                 goto fail;
284
285         cur_src = src;
286         cur_dst = dst;
287
288         printf("test default bulk enqueue / dequeue\n");
289         num_elems = 16;
290
291         cur_src = src;
292         cur_dst = dst;
293
294         ret = rte_ring_enqueue_bulk(r, cur_src, num_elems, NULL);
295         cur_src += num_elems;
296         if (ret == 0) {
297                 printf("Cannot enqueue\n");
298                 goto fail;
299         }
300         ret = rte_ring_enqueue_bulk(r, cur_src, num_elems, NULL);
301         cur_src += num_elems;
302         if (ret == 0) {
303                 printf("Cannot enqueue\n");
304                 goto fail;
305         }
306         ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
307         cur_dst += num_elems;
308         if (ret == 0) {
309                 printf("Cannot dequeue\n");
310                 goto fail;
311         }
312         ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
313         cur_dst += num_elems;
314         if (ret == 0) {
315                 printf("Cannot dequeue2\n");
316                 goto fail;
317         }
318
319         /* check data */
320         if (memcmp(src, dst, cur_dst - dst)) {
321                 rte_hexdump(stdout, "src", src, cur_src - src);
322                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
323                 printf("data after dequeue is not the same\n");
324                 goto fail;
325         }
326
327         cur_src = src;
328         cur_dst = dst;
329
330         ret = rte_ring_mp_enqueue(r, cur_src);
331         if (ret != 0)
332                 goto fail;
333
334         ret = rte_ring_mc_dequeue(r, cur_dst);
335         if (ret != 0)
336                 goto fail;
337
338         free(src);
339         free(dst);
340         return 0;
341
342  fail:
343         free(src);
344         free(dst);
345         return -1;
346 }
347
348 static int
349 test_ring_burst_basic(void)
350 {
351         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
352         int ret;
353         unsigned i;
354
355         /* alloc dummy object pointers */
356         src = malloc(RING_SIZE*2*sizeof(void *));
357         if (src == NULL)
358                 goto fail;
359
360         for (i = 0; i < RING_SIZE*2 ; i++) {
361                 src[i] = (void *)(unsigned long)i;
362         }
363         cur_src = src;
364
365         /* alloc some room for copied objects */
366         dst = malloc(RING_SIZE*2*sizeof(void *));
367         if (dst == NULL)
368                 goto fail;
369
370         memset(dst, 0, RING_SIZE*2*sizeof(void *));
371         cur_dst = dst;
372
373         printf("Test SP & SC basic functions \n");
374         printf("enqueue 1 obj\n");
375         ret = rte_ring_sp_enqueue_burst(r, cur_src, 1, NULL);
376         cur_src += 1;
377         if ((ret & RTE_RING_SZ_MASK) != 1)
378                 goto fail;
379
380         printf("enqueue 2 objs\n");
381         ret = rte_ring_sp_enqueue_burst(r, cur_src, 2, NULL);
382         cur_src += 2;
383         if ((ret & RTE_RING_SZ_MASK) != 2)
384                 goto fail;
385
386         printf("enqueue MAX_BULK objs\n");
387         ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
388         cur_src += MAX_BULK;
389         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
390                 goto fail;
391
392         printf("dequeue 1 obj\n");
393         ret = rte_ring_sc_dequeue_burst(r, cur_dst, 1) ;
394         cur_dst += 1;
395         if ((ret & RTE_RING_SZ_MASK) != 1)
396                 goto fail;
397
398         printf("dequeue 2 objs\n");
399         ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
400         cur_dst += 2;
401         if ((ret & RTE_RING_SZ_MASK) != 2)
402                 goto fail;
403
404         printf("dequeue MAX_BULK objs\n");
405         ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
406         cur_dst += MAX_BULK;
407         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
408                 goto fail;
409
410         /* check data */
411         if (memcmp(src, dst, cur_dst - dst)) {
412                 rte_hexdump(stdout, "src", src, cur_src - src);
413                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
414                 printf("data after dequeue is not the same\n");
415                 goto fail;
416         }
417
418         cur_src = src;
419         cur_dst = dst;
420
421         printf("Test enqueue without enough memory space \n");
422         for (i = 0; i< (RING_SIZE/MAX_BULK - 1); i++) {
423                 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
424                 cur_src += MAX_BULK;
425                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK) {
426                         goto fail;
427                 }
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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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);
455                 cur_dst += MAX_BULK;
456                 if ((ret & RTE_RING_SZ_MASK) != 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);
462         cur_dst += 2;
463         if ((ret & RTE_RING_SZ_MASK) != 2)
464                 goto fail;
465
466         ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
467         cur_dst += MAX_BULK - 3;
468         if ((ret & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != MAX_BULK)
505                 goto fail;
506
507         printf("dequeue 1 obj\n");
508         ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1);
509         cur_dst += 1;
510         if ((ret & RTE_RING_SZ_MASK) != 1)
511                 goto fail;
512
513         printf("dequeue 2 objs\n");
514         ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
515         cur_dst += 2;
516         if ((ret & RTE_RING_SZ_MASK) != 2)
517                 goto fail;
518
519         printf("dequeue MAX_BULK objs\n");
520         ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
521         cur_dst += MAX_BULK;
522         if ((ret & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != MAX_BULK)
541                         goto fail;
542                 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
543                 cur_dst += MAX_BULK;
544                 if ((ret & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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);
582                 cur_dst += MAX_BULK;
583                 if ((ret & RTE_RING_SZ_MASK) != 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);
589         cur_dst += 2;
590         if ((ret & RTE_RING_SZ_MASK) != 2)
591                 goto fail;
592
593         ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
594         cur_dst += MAX_BULK - 3;
595         if ((ret & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 2)
614                 goto fail;
615
616         ret = rte_ring_dequeue_burst(r, cur_dst, 2);
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 & RTE_RING_SZ_MASK) != 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);
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(void)
772 {
773         /* some more basic operations */
774         if (test_ring_basic_ex() < 0)
775                 return -1;
776
777         rte_atomic32_init(&synchro);
778
779         if (r == NULL)
780                 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
781         if (r == NULL)
782                 return -1;
783
784         /* retrieve the ring from its name */
785         if (rte_ring_lookup("test") != r) {
786                 printf("Cannot lookup ring from its name\n");
787                 return -1;
788         }
789
790         /* burst operations */
791         if (test_ring_burst_basic() < 0)
792                 return -1;
793
794         /* basic operations */
795         if (test_ring_basic() < 0)
796                 return -1;
797
798         /* basic operations */
799         if ( test_create_count_odd() < 0){
800                         printf ("Test failed to detect odd count\n");
801                         return -1;
802                 }
803                 else
804                         printf ( "Test detected odd count\n");
805
806         if ( test_lookup_null() < 0){
807                                 printf ("Test failed to detect NULL ring lookup\n");
808                                 return -1;
809                         }
810                         else
811                                 printf ( "Test detected NULL ring lookup \n");
812
813         /* test of creating ring with wrong size */
814         if (test_ring_creation_with_wrong_size() < 0)
815                 return -1;
816
817         /* test of creation ring with an used name */
818         if (test_ring_creation_with_an_used_name() < 0)
819                 return -1;
820
821         /* dump the ring status */
822         rte_ring_list_dump(stdout);
823
824         return 0;
825 }
826
827 REGISTER_TEST_COMMAND(ring_autotest, test_ring);