New upstream version 17.08
[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_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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != 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 & RTE_RING_SZ_MASK) != MAX_BULK) {
427                         goto fail;
428                 }
429         }
430
431         printf("Enqueue 2 objects, free entries = MAX_BULK - 2  \n");
432         ret = rte_ring_sp_enqueue_burst(r, cur_src, 2, NULL);
433         cur_src += 2;
434         if ((ret & RTE_RING_SZ_MASK) != 2)
435                 goto fail;
436
437         printf("Enqueue the remaining entries = MAX_BULK - 2  \n");
438         /* Always one free entry left */
439         ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
440         cur_src += MAX_BULK - 3;
441         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
442                 goto fail;
443
444         printf("Test if ring is full  \n");
445         if (rte_ring_full(r) != 1)
446                 goto fail;
447
448         printf("Test enqueue for a full entry  \n");
449         ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
450         if ((ret & RTE_RING_SZ_MASK) != 0)
451                 goto fail;
452
453         printf("Test dequeue without enough objects \n");
454         for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
455                 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
456                 cur_dst += MAX_BULK;
457                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
458                         goto fail;
459         }
460
461         /* Available memory space for the exact MAX_BULK entries */
462         ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2, NULL);
463         cur_dst += 2;
464         if ((ret & RTE_RING_SZ_MASK) != 2)
465                 goto fail;
466
467         ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
468         cur_dst += MAX_BULK - 3;
469         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
470                 goto fail;
471
472         printf("Test if ring is empty \n");
473         /* Check if ring is empty */
474         if (1 != rte_ring_empty(r))
475                 goto fail;
476
477         /* check data */
478         if (memcmp(src, dst, cur_dst - dst)) {
479                 rte_hexdump(stdout, "src", src, cur_src - src);
480                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
481                 printf("data after dequeue is not the same\n");
482                 goto fail;
483         }
484
485         cur_src = src;
486         cur_dst = dst;
487
488         printf("Test MP & MC basic functions \n");
489
490         printf("enqueue 1 obj\n");
491         ret = rte_ring_mp_enqueue_burst(r, cur_src, 1, NULL);
492         cur_src += 1;
493         if ((ret & RTE_RING_SZ_MASK) != 1)
494                 goto fail;
495
496         printf("enqueue 2 objs\n");
497         ret = rte_ring_mp_enqueue_burst(r, cur_src, 2, NULL);
498         cur_src += 2;
499         if ((ret & RTE_RING_SZ_MASK) != 2)
500                 goto fail;
501
502         printf("enqueue MAX_BULK objs\n");
503         ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
504         cur_src += MAX_BULK;
505         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
506                 goto fail;
507
508         printf("dequeue 1 obj\n");
509         ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1, NULL);
510         cur_dst += 1;
511         if ((ret & RTE_RING_SZ_MASK) != 1)
512                 goto fail;
513
514         printf("dequeue 2 objs\n");
515         ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2, NULL);
516         cur_dst += 2;
517         if ((ret & RTE_RING_SZ_MASK) != 2)
518                 goto fail;
519
520         printf("dequeue MAX_BULK objs\n");
521         ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
522         cur_dst += MAX_BULK;
523         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
524                 goto fail;
525
526         /* check data */
527         if (memcmp(src, dst, cur_dst - dst)) {
528                 rte_hexdump(stdout, "src", src, cur_src - src);
529                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
530                 printf("data after dequeue is not the same\n");
531                 goto fail;
532         }
533
534         cur_src = src;
535         cur_dst = dst;
536
537         printf("fill and empty the ring\n");
538         for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
539                 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
540                 cur_src += MAX_BULK;
541                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
542                         goto fail;
543                 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
544                 cur_dst += MAX_BULK;
545                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
546                         goto fail;
547         }
548
549         /* check data */
550         if (memcmp(src, dst, cur_dst - dst)) {
551                 rte_hexdump(stdout, "src", src, cur_src - src);
552                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
553                 printf("data after dequeue is not the same\n");
554                 goto fail;
555         }
556
557         cur_src = src;
558         cur_dst = dst;
559
560         printf("Test enqueue without enough memory space \n");
561         for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
562                 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
563                 cur_src += MAX_BULK;
564                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
565                         goto fail;
566         }
567
568         /* Available memory space for the exact MAX_BULK objects */
569         ret = rte_ring_mp_enqueue_burst(r, cur_src, 2, NULL);
570         cur_src += 2;
571         if ((ret & RTE_RING_SZ_MASK) != 2)
572                 goto fail;
573
574         ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK, NULL);
575         cur_src += MAX_BULK - 3;
576         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
577                 goto fail;
578
579
580         printf("Test dequeue without enough objects \n");
581         for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
582                 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
583                 cur_dst += MAX_BULK;
584                 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
585                         goto fail;
586         }
587
588         /* Available objects - the exact MAX_BULK */
589         ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2, NULL);
590         cur_dst += 2;
591         if ((ret & RTE_RING_SZ_MASK) != 2)
592                 goto fail;
593
594         ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK, NULL);
595         cur_dst += MAX_BULK - 3;
596         if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
597                 goto fail;
598
599         /* check data */
600         if (memcmp(src, dst, cur_dst - dst)) {
601                 rte_hexdump(stdout, "src", src, cur_src - src);
602                 rte_hexdump(stdout, "dst", dst, cur_dst - dst);
603                 printf("data after dequeue is not the same\n");
604                 goto fail;
605         }
606
607         cur_src = src;
608         cur_dst = dst;
609
610         printf("Covering rte_ring_enqueue_burst functions \n");
611
612         ret = rte_ring_enqueue_burst(r, cur_src, 2, NULL);
613         cur_src += 2;
614         if ((ret & RTE_RING_SZ_MASK) != 2)
615                 goto fail;
616
617         ret = rte_ring_dequeue_burst(r, cur_dst, 2, NULL);
618         cur_dst += 2;
619         if (ret != 2)
620                 goto fail;
621
622         /* Free memory before test completed */
623         free(src);
624         free(dst);
625         return 0;
626
627  fail:
628         free(src);
629         free(dst);
630         return -1;
631 }
632
633 /*
634  * it will always fail to create ring with a wrong ring size number in this function
635  */
636 static int
637 test_ring_creation_with_wrong_size(void)
638 {
639         struct rte_ring * rp = NULL;
640
641         /* Test if ring size is not power of 2 */
642         rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0);
643         if (NULL != rp) {
644                 return -1;
645         }
646
647         /* Test if ring size is exceeding the limit */
648         rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0);
649         if (NULL != rp) {
650                 return -1;
651         }
652         return 0;
653 }
654
655 /*
656  * it tests if it would always fail to create ring with an used ring name
657  */
658 static int
659 test_ring_creation_with_an_used_name(void)
660 {
661         struct rte_ring * rp;
662
663         rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
664         if (NULL != rp)
665                 return -1;
666
667         return 0;
668 }
669
670 /*
671  * Test to if a non-power of 2 count causes the create
672  * function to fail correctly
673  */
674 static int
675 test_create_count_odd(void)
676 {
677         struct rte_ring *r = rte_ring_create("test_ring_count",
678                         4097, SOCKET_ID_ANY, 0 );
679         if(r != NULL){
680                 return -1;
681         }
682         return 0;
683 }
684
685 static int
686 test_lookup_null(void)
687 {
688         struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
689         if (rlp ==NULL)
690         if (rte_errno != ENOENT){
691                 printf( "test failed to returnn error on null pointer\n");
692                 return -1;
693         }
694         return 0;
695 }
696
697 /*
698  * it tests some more basic ring operations
699  */
700 static int
701 test_ring_basic_ex(void)
702 {
703         int ret = -1;
704         unsigned i;
705         struct rte_ring * rp;
706         void **obj = NULL;
707
708         obj = rte_calloc("test_ring_basic_ex_malloc", RING_SIZE, sizeof(void *), 0);
709         if (obj == NULL) {
710                 printf("test_ring_basic_ex fail to rte_malloc\n");
711                 goto fail_test;
712         }
713
714         rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY,
715                         RING_F_SP_ENQ | RING_F_SC_DEQ);
716         if (rp == NULL) {
717                 printf("test_ring_basic_ex fail to create ring\n");
718                 goto fail_test;
719         }
720
721         if (rte_ring_lookup("test_ring_basic_ex") != rp) {
722                 goto fail_test;
723         }
724
725         if (rte_ring_empty(rp) != 1) {
726                 printf("test_ring_basic_ex ring is not empty but it should be\n");
727                 goto fail_test;
728         }
729
730         printf("%u ring entries are now free\n", rte_ring_free_count(rp));
731
732         for (i = 0; i < RING_SIZE; i ++) {
733                 rte_ring_enqueue(rp, obj[i]);
734         }
735
736         if (rte_ring_full(rp) != 1) {
737                 printf("test_ring_basic_ex ring is not full but it should be\n");
738                 goto fail_test;
739         }
740
741         for (i = 0; i < RING_SIZE; i ++) {
742                 rte_ring_dequeue(rp, &obj[i]);
743         }
744
745         if (rte_ring_empty(rp) != 1) {
746                 printf("test_ring_basic_ex ring is not empty but it should be\n");
747                 goto fail_test;
748         }
749
750         /* Covering the ring burst operation */
751         ret = rte_ring_enqueue_burst(rp, obj, 2, NULL);
752         if ((ret & RTE_RING_SZ_MASK) != 2) {
753                 printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n");
754                 goto fail_test;
755         }
756
757         ret = rte_ring_dequeue_burst(rp, obj, 2, NULL);
758         if (ret != 2) {
759                 printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n");
760                 goto fail_test;
761         }
762
763         ret = 0;
764 fail_test:
765         if (obj != NULL)
766                 rte_free(obj);
767
768         return ret;
769 }
770
771 static int
772 test_ring_with_exact_size(void)
773 {
774         struct rte_ring *std_ring = NULL, *exact_sz_ring = NULL;
775         void *ptr_array[16];
776         static const unsigned int ring_sz = RTE_DIM(ptr_array);
777         unsigned int i;
778         int ret = -1;
779
780         std_ring = rte_ring_create("std", ring_sz, rte_socket_id(),
781                         RING_F_SP_ENQ | RING_F_SC_DEQ);
782         if (std_ring == NULL) {
783                 printf("%s: error, can't create std ring\n", __func__);
784                 goto end;
785         }
786         exact_sz_ring = rte_ring_create("exact sz", ring_sz, rte_socket_id(),
787                         RING_F_SP_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ);
788         if (exact_sz_ring == NULL) {
789                 printf("%s: error, can't create exact size ring\n", __func__);
790                 goto end;
791         }
792
793         /*
794          * Check that the exact size ring is bigger than the standard ring
795          */
796         if (rte_ring_get_size(std_ring) >= rte_ring_get_size(exact_sz_ring)) {
797                 printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n",
798                                 __func__,
799                                 rte_ring_get_size(std_ring),
800                                 rte_ring_get_size(exact_sz_ring));
801                 goto end;
802         }
803         /*
804          * check that the exact_sz_ring can hold one more element than the
805          * standard ring. (16 vs 15 elements)
806          */
807         for (i = 0; i < ring_sz - 1; i++) {
808                 rte_ring_enqueue(std_ring, NULL);
809                 rte_ring_enqueue(exact_sz_ring, NULL);
810         }
811         if (rte_ring_enqueue(std_ring, NULL) != -ENOBUFS) {
812                 printf("%s: error, unexpected successful enqueue\n", __func__);
813                 goto end;
814         }
815         if (rte_ring_enqueue(exact_sz_ring, NULL) == -ENOBUFS) {
816                 printf("%s: error, enqueue failed\n", __func__);
817                 goto end;
818         }
819
820         /* check that dequeue returns the expected number of elements */
821         if (rte_ring_dequeue_burst(exact_sz_ring, ptr_array,
822                         RTE_DIM(ptr_array), NULL) != ring_sz) {
823                 printf("%s: error, failed to dequeue expected nb of elements\n",
824                                 __func__);
825                 goto end;
826         }
827
828         /* check that the capacity function returns expected value */
829         if (rte_ring_get_capacity(exact_sz_ring) != ring_sz) {
830                 printf("%s: error, incorrect ring capacity reported\n",
831                                 __func__);
832                 goto end;
833         }
834
835         ret = 0; /* all ok if we get here */
836 end:
837         rte_ring_free(std_ring);
838         rte_ring_free(exact_sz_ring);
839         return ret;
840 }
841
842 static int
843 test_ring(void)
844 {
845         /* some more basic operations */
846         if (test_ring_basic_ex() < 0)
847                 return -1;
848
849         rte_atomic32_init(&synchro);
850
851         if (r == NULL)
852                 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
853         if (r == NULL)
854                 return -1;
855
856         /* retrieve the ring from its name */
857         if (rte_ring_lookup("test") != r) {
858                 printf("Cannot lookup ring from its name\n");
859                 return -1;
860         }
861
862         /* burst operations */
863         if (test_ring_burst_basic() < 0)
864                 return -1;
865
866         /* basic operations */
867         if (test_ring_basic() < 0)
868                 return -1;
869
870         /* basic operations */
871         if ( test_create_count_odd() < 0){
872                         printf ("Test failed to detect odd count\n");
873                         return -1;
874                 }
875                 else
876                         printf ( "Test detected odd count\n");
877
878         if ( test_lookup_null() < 0){
879                                 printf ("Test failed to detect NULL ring lookup\n");
880                                 return -1;
881                         }
882                         else
883                                 printf ( "Test detected NULL ring lookup \n");
884
885         /* test of creating ring with wrong size */
886         if (test_ring_creation_with_wrong_size() < 0)
887                 return -1;
888
889         /* test of creation ring with an used name */
890         if (test_ring_creation_with_an_used_name() < 0)
891                 return -1;
892
893         if (test_ring_with_exact_size() < 0)
894                 return -1;
895
896         /* dump the ring status */
897         rte_ring_list_dump(stdout);
898
899         return 0;
900 }
901
902 REGISTER_TEST_COMMAND(ring_autotest, test_ring);