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