4 * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
42 #include <sys/queue.h>
44 #include <rte_common.h>
46 #include <rte_memory.h>
47 #include <rte_memzone.h>
48 #include <rte_launch.h>
49 #include <rte_cycles.h>
50 #include <rte_tailq.h>
52 #include <rte_per_lcore.h>
53 #include <rte_lcore.h>
54 #include <rte_atomic.h>
55 #include <rte_branch_prediction.h>
56 #include <rte_malloc.h>
58 #include <rte_random.h>
59 #include <rte_common.h>
60 #include <rte_errno.h>
61 #include <rte_hexdump.h>
63 #include <cmdline_parse.h>
71 * #. Basic tests: done on one core:
73 * - Using single producer/single consumer functions:
75 * - Enqueue one object, two objects, MAX_BULK objects
76 * - Dequeue one object, two objects, MAX_BULK objects
77 * - Check that dequeued pointers are correct
79 * - Using multi producers/multi consumers functions:
81 * - Enqueue one object, two objects, MAX_BULK objects
82 * - Dequeue one object, two objects, MAX_BULK objects
83 * - Check that dequeued pointers are correct
85 * - Test watermark and default bulk enqueue/dequeue:
88 * - Set default bulk value
89 * - Enqueue objects, check that -EDQUOT is returned when
90 * watermark is exceeded
91 * - Check that dequeued pointers are correct
93 * #. Check live watermark change
95 * - Start a loop on another lcore that will enqueue and dequeue
96 * objects in a ring. It will monitor the value of watermark.
97 * - At the same time, change the watermark on the master lcore.
98 * - The slave lcore will check that watermark changes from 16 to 32.
100 * #. Performance tests.
102 * Tests done in test_ring_perf.c
105 #define RING_SIZE 4096
110 static rte_atomic32_t synchro;
112 static struct rte_ring *r;
114 #define TEST_RING_VERIFY(exp) \
116 printf("error at %s:%d\tcondition " #exp " failed\n", \
117 __func__, __LINE__); \
122 #define TEST_RING_FULL_EMTPY_ITER 8
125 check_live_watermark_change(__attribute__((unused)) void *dummy)
127 uint64_t hz = rte_get_timer_hz();
128 void *obj_table[MAX_BULK];
129 unsigned watermark, watermark_old = 16;
130 uint64_t cur_time, end_time;
135 /* init the object table */
136 memset(obj_table, 0, sizeof(obj_table));
137 end_time = rte_get_timer_cycles() + (hz * 2);
139 /* check that bulk and watermark are 4 and 32 (respectively) */
142 /* add in ring until we reach watermark */
144 for (i = 0; i < 16; i ++) {
147 ret = rte_ring_enqueue_bulk(r, obj_table, count);
150 if (ret != -EDQUOT) {
151 printf("Cannot enqueue objects, or watermark not "
152 "reached (ret=%d)\n", ret);
156 /* read watermark, the only change allowed is from 16 to 32 */
157 watermark = r->prod.watermark;
158 if (watermark != watermark_old &&
159 (watermark_old != 16 || watermark != 32)) {
160 printf("Bad watermark change %u -> %u\n", watermark_old,
164 watermark_old = watermark;
166 /* dequeue objects from ring */
168 ret = rte_ring_dequeue_bulk(r, obj_table, count);
170 printf("Cannot dequeue (ret=%d)\n", ret);
175 cur_time = rte_get_timer_cycles();
176 diff = end_time - cur_time;
179 if (watermark_old != 32 ) {
180 printf(" watermark was not updated (wm=%u)\n",
189 test_live_watermark_change(void)
191 unsigned lcore_id = rte_lcore_id();
192 unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
194 printf("Test watermark live modification\n");
195 rte_ring_set_water_mark(r, 16);
197 /* launch a thread that will enqueue and dequeue, checking
198 * watermark and quota */
199 rte_eal_remote_launch(check_live_watermark_change, NULL, lcore_id2);
202 rte_ring_set_water_mark(r, 32);
205 if (rte_eal_wait_lcore(lcore_id2) < 0)
211 /* Test for catch on invalid watermark values */
213 test_set_watermark( void ){
217 struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
219 printf( " ring lookup failed\n" );
222 count = r->prod.size*2;
223 setwm = rte_ring_set_water_mark(r, count);
224 if (setwm != -EINVAL){
225 printf("Test failed to detect invalid watermark count value\n");
230 rte_ring_set_water_mark(r, count);
231 if (r->prod.watermark != r->prod.size) {
232 printf("Test failed to detect invalid watermark count value\n");
242 * helper routine for test_ring_basic
245 test_ring_basic_full_empty(void * const src[], void *dst[])
248 const unsigned rsz = RING_SIZE - 1;
250 printf("Basic full/empty test\n");
252 for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) {
254 /* random shift in the ring */
255 rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
256 printf("%s: iteration %u, random shift: %u;\n",
258 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
260 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand));
263 TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
265 TEST_RING_VERIFY(0 == rte_ring_free_count(r));
266 TEST_RING_VERIFY(rsz == rte_ring_count(r));
267 TEST_RING_VERIFY(rte_ring_full(r));
268 TEST_RING_VERIFY(0 == rte_ring_empty(r));
271 TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz));
272 TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
273 TEST_RING_VERIFY(0 == rte_ring_count(r));
274 TEST_RING_VERIFY(0 == rte_ring_full(r));
275 TEST_RING_VERIFY(rte_ring_empty(r));
278 TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
285 test_ring_basic(void)
287 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
289 unsigned i, num_elems;
291 /* alloc dummy object pointers */
292 src = malloc(RING_SIZE*2*sizeof(void *));
296 for (i = 0; i < RING_SIZE*2 ; i++) {
297 src[i] = (void *)(unsigned long)i;
301 /* alloc some room for copied objects */
302 dst = malloc(RING_SIZE*2*sizeof(void *));
306 memset(dst, 0, RING_SIZE*2*sizeof(void *));
309 printf("enqueue 1 obj\n");
310 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1);
315 printf("enqueue 2 objs\n");
316 ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2);
321 printf("enqueue MAX_BULK objs\n");
322 ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK);
327 printf("dequeue 1 obj\n");
328 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
333 printf("dequeue 2 objs\n");
334 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
339 printf("dequeue MAX_BULK objs\n");
340 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
346 if (memcmp(src, dst, cur_dst - dst)) {
347 rte_hexdump("src", src, cur_src - src);
348 rte_hexdump("dst", dst, cur_dst - dst);
349 printf("data after dequeue is not the same\n");
355 printf("enqueue 1 obj\n");
356 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1);
361 printf("enqueue 2 objs\n");
362 ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2);
367 printf("enqueue MAX_BULK objs\n");
368 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
373 printf("dequeue 1 obj\n");
374 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
379 printf("dequeue 2 objs\n");
380 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
385 printf("dequeue MAX_BULK objs\n");
386 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
392 if (memcmp(src, dst, cur_dst - dst)) {
393 rte_hexdump("src", src, cur_src - src);
394 rte_hexdump("dst", dst, cur_dst - dst);
395 printf("data after dequeue is not the same\n");
401 printf("fill and empty the ring\n");
402 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
403 ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
407 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
414 if (memcmp(src, dst, cur_dst - dst)) {
415 rte_hexdump("src", src, cur_src - src);
416 rte_hexdump("dst", dst, cur_dst - dst);
417 printf("data after dequeue is not the same\n");
421 if (test_ring_basic_full_empty(src, dst) != 0)
427 printf("test watermark and default bulk enqueue / dequeue\n");
428 rte_ring_set_water_mark(r, 20);
434 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
435 cur_src += num_elems;
437 printf("Cannot enqueue\n");
440 ret = rte_ring_enqueue_bulk(r, cur_src, num_elems);
441 cur_src += num_elems;
442 if (ret != -EDQUOT) {
443 printf("Watermark not exceeded\n");
446 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
447 cur_dst += num_elems;
449 printf("Cannot dequeue\n");
452 ret = rte_ring_dequeue_bulk(r, cur_dst, num_elems);
453 cur_dst += num_elems;
455 printf("Cannot dequeue2\n");
460 if (memcmp(src, dst, cur_dst - dst)) {
461 rte_hexdump("src", src, cur_src - src);
462 rte_hexdump("dst", dst, cur_dst - dst);
463 printf("data after dequeue is not the same\n");
470 ret = rte_ring_mp_enqueue(r, cur_src);
474 ret = rte_ring_mc_dequeue(r, cur_dst);
493 test_ring_burst_basic(void)
495 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
499 /* alloc dummy object pointers */
500 src = malloc(RING_SIZE*2*sizeof(void *));
504 for (i = 0; i < RING_SIZE*2 ; i++) {
505 src[i] = (void *)(unsigned long)i;
509 /* alloc some room for copied objects */
510 dst = malloc(RING_SIZE*2*sizeof(void *));
514 memset(dst, 0, RING_SIZE*2*sizeof(void *));
517 printf("Test SP & SC basic functions \n");
518 printf("enqueue 1 obj\n");
519 ret = rte_ring_sp_enqueue_burst(r, cur_src, 1);
521 if ((ret & RTE_RING_SZ_MASK) != 1)
524 printf("enqueue 2 objs\n");
525 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
527 if ((ret & RTE_RING_SZ_MASK) != 2)
530 printf("enqueue MAX_BULK objs\n");
531 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK) ;
533 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
536 printf("dequeue 1 obj\n");
537 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 1) ;
539 if ((ret & RTE_RING_SZ_MASK) != 1)
542 printf("dequeue 2 objs\n");
543 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
545 if ((ret & RTE_RING_SZ_MASK) != 2)
548 printf("dequeue MAX_BULK objs\n");
549 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
551 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
555 if (memcmp(src, dst, cur_dst - dst)) {
556 rte_hexdump("src", src, cur_src - src);
557 rte_hexdump("dst", dst, cur_dst - dst);
558 printf("data after dequeue is not the same\n");
565 printf("Test enqueue without enough memory space \n");
566 for (i = 0; i< (RING_SIZE/MAX_BULK - 1); i++) {
567 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
569 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK) {
574 printf("Enqueue 2 objects, free entries = MAX_BULK - 2 \n");
575 ret = rte_ring_sp_enqueue_burst(r, cur_src, 2);
577 if ((ret & RTE_RING_SZ_MASK) != 2)
580 printf("Enqueue the remaining entries = MAX_BULK - 2 \n");
581 /* Always one free entry left */
582 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
583 cur_src += MAX_BULK - 3;
584 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
587 printf("Test if ring is full \n");
588 if (rte_ring_full(r) != 1)
591 printf("Test enqueue for a full entry \n");
592 ret = rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
593 if ((ret & RTE_RING_SZ_MASK) != 0)
596 printf("Test dequeue without enough objects \n");
597 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
598 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
600 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
604 /* Available memory space for the exact MAX_BULK entries */
605 ret = rte_ring_sc_dequeue_burst(r, cur_dst, 2);
607 if ((ret & RTE_RING_SZ_MASK) != 2)
610 ret = rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
611 cur_dst += MAX_BULK - 3;
612 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
615 printf("Test if ring is empty \n");
616 /* Check if ring is empty */
617 if (1 != rte_ring_empty(r))
621 if (memcmp(src, dst, cur_dst - dst)) {
622 rte_hexdump("src", src, cur_src - src);
623 rte_hexdump("dst", dst, cur_dst - dst);
624 printf("data after dequeue is not the same\n");
631 printf("Test MP & MC basic functions \n");
633 printf("enqueue 1 obj\n");
634 ret = rte_ring_mp_enqueue_burst(r, cur_src, 1);
636 if ((ret & RTE_RING_SZ_MASK) != 1)
639 printf("enqueue 2 objs\n");
640 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
642 if ((ret & RTE_RING_SZ_MASK) != 2)
645 printf("enqueue MAX_BULK objs\n");
646 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
648 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
651 printf("dequeue 1 obj\n");
652 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 1);
654 if ((ret & RTE_RING_SZ_MASK) != 1)
657 printf("dequeue 2 objs\n");
658 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
660 if ((ret & RTE_RING_SZ_MASK) != 2)
663 printf("dequeue MAX_BULK objs\n");
664 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
666 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
670 if (memcmp(src, dst, cur_dst - dst)) {
671 rte_hexdump("src", src, cur_src - src);
672 rte_hexdump("dst", dst, cur_dst - dst);
673 printf("data after dequeue is not the same\n");
680 printf("fill and empty the ring\n");
681 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
682 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
684 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
686 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
688 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
693 if (memcmp(src, dst, cur_dst - dst)) {
694 rte_hexdump("src", src, cur_src - src);
695 rte_hexdump("dst", dst, cur_dst - dst);
696 printf("data after dequeue is not the same\n");
703 printf("Test enqueue without enough memory space \n");
704 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
705 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
707 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
711 /* Available memory space for the exact MAX_BULK objects */
712 ret = rte_ring_mp_enqueue_burst(r, cur_src, 2);
714 if ((ret & RTE_RING_SZ_MASK) != 2)
717 ret = rte_ring_mp_enqueue_burst(r, cur_src, MAX_BULK);
718 cur_src += MAX_BULK - 3;
719 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
723 printf("Test dequeue without enough objects \n");
724 for (i = 0; i<RING_SIZE/MAX_BULK - 1; i++) {
725 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
727 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK)
731 /* Available objects - the exact MAX_BULK */
732 ret = rte_ring_mc_dequeue_burst(r, cur_dst, 2);
734 if ((ret & RTE_RING_SZ_MASK) != 2)
737 ret = rte_ring_mc_dequeue_burst(r, cur_dst, MAX_BULK);
738 cur_dst += MAX_BULK - 3;
739 if ((ret & RTE_RING_SZ_MASK) != MAX_BULK - 3)
743 if (memcmp(src, dst, cur_dst - dst)) {
744 rte_hexdump("src", src, cur_src - src);
745 rte_hexdump("dst", dst, cur_dst - dst);
746 printf("data after dequeue is not the same\n");
753 printf("Covering rte_ring_enqueue_burst functions \n");
755 ret = rte_ring_enqueue_burst(r, cur_src, 2);
757 if ((ret & RTE_RING_SZ_MASK) != 2)
760 ret = rte_ring_dequeue_burst(r, cur_dst, 2);
765 /* Free memory before test completed */
781 test_ring_stats(void)
784 #ifndef RTE_LIBRTE_RING_DEBUG
785 printf("Enable RTE_LIBRTE_RING_DEBUG to test ring stats.\n");
788 void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
791 unsigned num_items = 0;
792 unsigned failed_enqueue_ops = 0;
793 unsigned failed_enqueue_items = 0;
794 unsigned failed_dequeue_ops = 0;
795 unsigned failed_dequeue_items = 0;
796 unsigned last_enqueue_ops = 0;
797 unsigned last_enqueue_items = 0;
798 unsigned last_quota_ops = 0;
799 unsigned last_quota_items = 0;
800 unsigned lcore_id = rte_lcore_id();
801 struct rte_ring_debug_stats *ring_stats = &r->stats[lcore_id];
803 printf("Test the ring stats.\n");
805 /* Reset the watermark in case it was set in another test. */
806 rte_ring_set_water_mark(r, 0);
808 /* Reset the ring stats. */
809 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
811 /* Allocate some dummy object pointers. */
812 src = malloc(RING_SIZE*2*sizeof(void *));
816 for (i = 0; i < RING_SIZE*2 ; i++) {
817 src[i] = (void *)(unsigned long)i;
820 /* Allocate some memory for copied objects. */
821 dst = malloc(RING_SIZE*2*sizeof(void *));
825 memset(dst, 0, RING_SIZE*2*sizeof(void *));
827 /* Set the head and tail pointers. */
831 /* Do Enqueue tests. */
832 printf("Test the dequeue stats.\n");
834 /* Fill the ring up to RING_SIZE -1. */
835 printf("Fill the ring.\n");
836 for (i = 0; i< (RING_SIZE/MAX_BULK); i++) {
837 rte_ring_sp_enqueue_burst(r, cur_src, MAX_BULK);
841 /* Adjust for final enqueue = MAX_BULK -1. */
844 printf("Verify that the ring is full.\n");
845 if (rte_ring_full(r) != 1)
849 printf("Verify the enqueue success stats.\n");
850 /* Stats should match above enqueue operations to fill the ring. */
851 if (ring_stats->enq_success_bulk != (RING_SIZE/MAX_BULK))
854 /* Current max objects is RING_SIZE -1. */
855 if (ring_stats->enq_success_objs != RING_SIZE -1)
858 /* Shouldn't have any failures yet. */
859 if (ring_stats->enq_fail_bulk != 0)
861 if (ring_stats->enq_fail_objs != 0)
865 printf("Test stats for SP burst enqueue to a full ring.\n");
867 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
868 if ((ret & RTE_RING_SZ_MASK) != 0)
871 failed_enqueue_ops += 1;
872 failed_enqueue_items += num_items;
874 /* The enqueue should have failed. */
875 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
877 if (ring_stats->enq_fail_objs != failed_enqueue_items)
881 printf("Test stats for SP bulk enqueue to a full ring.\n");
883 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
887 failed_enqueue_ops += 1;
888 failed_enqueue_items += num_items;
890 /* The enqueue should have failed. */
891 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
893 if (ring_stats->enq_fail_objs != failed_enqueue_items)
897 printf("Test stats for MP burst enqueue to a full ring.\n");
899 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
900 if ((ret & RTE_RING_SZ_MASK) != 0)
903 failed_enqueue_ops += 1;
904 failed_enqueue_items += num_items;
906 /* The enqueue should have failed. */
907 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
909 if (ring_stats->enq_fail_objs != failed_enqueue_items)
913 printf("Test stats for MP bulk enqueue to a full ring.\n");
915 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
919 failed_enqueue_ops += 1;
920 failed_enqueue_items += num_items;
922 /* The enqueue should have failed. */
923 if (ring_stats->enq_fail_bulk != failed_enqueue_ops)
925 if (ring_stats->enq_fail_objs != failed_enqueue_items)
929 /* Do Dequeue tests. */
930 printf("Test the dequeue stats.\n");
932 printf("Empty the ring.\n");
933 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
934 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
938 /* There was only RING_SIZE -1 objects to dequeue. */
941 printf("Verify ring is empty.\n");
942 if (1 != rte_ring_empty(r))
945 printf("Verify the dequeue success stats.\n");
946 /* Stats should match above dequeue operations. */
947 if (ring_stats->deq_success_bulk != (RING_SIZE/MAX_BULK))
950 /* Objects dequeued is RING_SIZE -1. */
951 if (ring_stats->deq_success_objs != RING_SIZE -1)
954 /* Shouldn't have any dequeue failure stats yet. */
955 if (ring_stats->deq_fail_bulk != 0)
958 printf("Test stats for SC burst dequeue with an empty ring.\n");
960 ret = rte_ring_sc_dequeue_burst(r, cur_dst, num_items);
961 if ((ret & RTE_RING_SZ_MASK) != 0)
964 failed_dequeue_ops += 1;
965 failed_dequeue_items += num_items;
967 /* The dequeue should have failed. */
968 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
970 if (ring_stats->deq_fail_objs != failed_dequeue_items)
974 printf("Test stats for SC bulk dequeue with an empty ring.\n");
976 ret = rte_ring_sc_dequeue_bulk(r, cur_dst, num_items);
980 failed_dequeue_ops += 1;
981 failed_dequeue_items += num_items;
983 /* The dequeue should have failed. */
984 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
986 if (ring_stats->deq_fail_objs != failed_dequeue_items)
990 printf("Test stats for MC burst dequeue with an empty ring.\n");
992 ret = rte_ring_mc_dequeue_burst(r, cur_dst, num_items);
993 if ((ret & RTE_RING_SZ_MASK) != 0)
995 failed_dequeue_ops += 1;
996 failed_dequeue_items += num_items;
998 /* The dequeue should have failed. */
999 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1001 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1005 printf("Test stats for MC bulk dequeue with an empty ring.\n");
1007 ret = rte_ring_mc_dequeue_bulk(r, cur_dst, num_items);
1011 failed_dequeue_ops += 1;
1012 failed_dequeue_items += num_items;
1014 /* The dequeue should have failed. */
1015 if (ring_stats->deq_fail_bulk != failed_dequeue_ops)
1017 if (ring_stats->deq_fail_objs != failed_dequeue_items)
1021 printf("Test total enqueue/dequeue stats.\n");
1022 /* At this point the enqueue and dequeue stats should be the same. */
1023 if (ring_stats->enq_success_bulk != ring_stats->deq_success_bulk)
1025 if (ring_stats->enq_success_objs != ring_stats->deq_success_objs)
1027 if (ring_stats->enq_fail_bulk != ring_stats->deq_fail_bulk)
1029 if (ring_stats->enq_fail_objs != ring_stats->deq_fail_objs)
1033 /* Watermark Tests. */
1034 printf("Test the watermark/quota stats.\n");
1036 printf("Verify the initial watermark stats.\n");
1037 /* Watermark stats should be 0 since there is no watermark. */
1038 if (ring_stats->enq_quota_bulk != 0)
1040 if (ring_stats->enq_quota_objs != 0)
1043 /* Set a watermark. */
1044 rte_ring_set_water_mark(r, 16);
1046 /* Reset pointers. */
1050 last_enqueue_ops = ring_stats->enq_success_bulk;
1051 last_enqueue_items = ring_stats->enq_success_objs;
1054 printf("Test stats for SP burst enqueue below watermark.\n");
1056 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1057 if ((ret & RTE_RING_SZ_MASK) != num_items)
1060 /* Watermark stats should still be 0. */
1061 if (ring_stats->enq_quota_bulk != 0)
1063 if (ring_stats->enq_quota_objs != 0)
1066 /* Success stats should have increased. */
1067 if (ring_stats->enq_success_bulk != last_enqueue_ops + 1)
1069 if (ring_stats->enq_success_objs != last_enqueue_items + num_items)
1072 last_enqueue_ops = ring_stats->enq_success_bulk;
1073 last_enqueue_items = ring_stats->enq_success_objs;
1076 printf("Test stats for SP burst enqueue at watermark.\n");
1078 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1079 if ((ret & RTE_RING_SZ_MASK) != num_items)
1082 /* Watermark stats should have changed. */
1083 if (ring_stats->enq_quota_bulk != 1)
1085 if (ring_stats->enq_quota_objs != num_items)
1088 last_quota_ops = ring_stats->enq_quota_bulk;
1089 last_quota_items = ring_stats->enq_quota_objs;
1092 printf("Test stats for SP burst enqueue above watermark.\n");
1094 ret = rte_ring_sp_enqueue_burst(r, cur_src, num_items);
1095 if ((ret & RTE_RING_SZ_MASK) != num_items)
1098 /* Watermark stats should have changed. */
1099 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1101 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1104 last_quota_ops = ring_stats->enq_quota_bulk;
1105 last_quota_items = ring_stats->enq_quota_objs;
1108 printf("Test stats for MP burst enqueue above watermark.\n");
1110 ret = rte_ring_mp_enqueue_burst(r, cur_src, num_items);
1111 if ((ret & RTE_RING_SZ_MASK) != num_items)
1114 /* Watermark stats should have changed. */
1115 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1117 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1120 last_quota_ops = ring_stats->enq_quota_bulk;
1121 last_quota_items = ring_stats->enq_quota_objs;
1124 printf("Test stats for SP bulk enqueue above watermark.\n");
1126 ret = rte_ring_sp_enqueue_bulk(r, cur_src, num_items);
1130 /* Watermark stats should have changed. */
1131 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1133 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1136 last_quota_ops = ring_stats->enq_quota_bulk;
1137 last_quota_items = ring_stats->enq_quota_objs;
1140 printf("Test stats for MP bulk enqueue above watermark.\n");
1142 ret = rte_ring_mp_enqueue_bulk(r, cur_src, num_items);
1146 /* Watermark stats should have changed. */
1147 if (ring_stats->enq_quota_bulk != last_quota_ops +1)
1149 if (ring_stats->enq_quota_objs != last_quota_items + num_items)
1152 printf("Test watermark success stats.\n");
1153 /* Success stats should be same as last non-watermarked enqueue. */
1154 if (ring_stats->enq_success_bulk != last_enqueue_ops)
1156 if (ring_stats->enq_success_objs != last_enqueue_items)
1162 /* Empty the ring. */
1163 for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
1164 rte_ring_sc_dequeue_burst(r, cur_dst, MAX_BULK);
1165 cur_dst += MAX_BULK;
1168 /* Reset the watermark. */
1169 rte_ring_set_water_mark(r, 0);
1171 /* Reset the ring stats. */
1172 memset(&r->stats[lcore_id], 0, sizeof(r->stats[lcore_id]));
1174 /* Free memory before test completed */
1191 * it will always fail to create ring with a wrong ring size number in this function
1194 test_ring_creation_with_wrong_size(void)
1196 struct rte_ring * rp = NULL;
1198 /* Test if ring size is not power of 2 */
1199 rp = rte_ring_create("test_bad_ring_size", RING_SIZE + 1, SOCKET_ID_ANY, 0);
1204 /* Test if ring size is exceeding the limit */
1205 rp = rte_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1), SOCKET_ID_ANY, 0);
1213 * it tests if it would always fail to create ring with an used ring name
1216 test_ring_creation_with_an_used_name(void)
1218 struct rte_ring * rp;
1220 rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1228 * Test to if a non-power of 2 count causes the create
1229 * function to fail correctly
1232 test_create_count_odd(void)
1234 struct rte_ring *r = rte_ring_create("test_ring_count",
1235 4097, SOCKET_ID_ANY, 0 );
1243 test_lookup_null(void)
1245 struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
1247 if (rte_errno != ENOENT){
1248 printf( "test failed to returnn error on null pointer\n");
1255 * it tests some more basic ring operations
1258 test_ring_basic_ex(void)
1262 struct rte_ring * rp;
1265 obj = (void **)rte_zmalloc("test_ring_basic_ex_malloc", (RING_SIZE * sizeof(void *)), 0);
1267 printf("test_ring_basic_ex fail to rte_malloc\n");
1271 rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY,
1272 RING_F_SP_ENQ | RING_F_SC_DEQ);
1274 printf("test_ring_basic_ex fail to create ring\n");
1278 if (rte_ring_lookup("test_ring_basic_ex") != rp) {
1282 if (rte_ring_empty(rp) != 1) {
1283 printf("test_ring_basic_ex ring is not empty but it should be\n");
1287 printf("%u ring entries are now free\n", rte_ring_free_count(rp));
1289 for (i = 0; i < RING_SIZE; i ++) {
1290 rte_ring_enqueue(rp, obj[i]);
1293 if (rte_ring_full(rp) != 1) {
1294 printf("test_ring_basic_ex ring is not full but it should be\n");
1298 for (i = 0; i < RING_SIZE; i ++) {
1299 rte_ring_dequeue(rp, &obj[i]);
1302 if (rte_ring_empty(rp) != 1) {
1303 printf("test_ring_basic_ex ring is not empty but it should be\n");
1307 /* Covering the ring burst operation */
1308 ret = rte_ring_enqueue_burst(rp, obj, 2);
1309 if ((ret & RTE_RING_SZ_MASK) != 2) {
1310 printf("test_ring_basic_ex: rte_ring_enqueue_burst fails \n");
1314 ret = rte_ring_dequeue_burst(rp, obj, 2);
1316 printf("test_ring_basic_ex: rte_ring_dequeue_burst fails \n");
1331 /* some more basic operations */
1332 if (test_ring_basic_ex() < 0)
1335 rte_atomic32_init(&synchro);
1338 r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
1342 /* retrieve the ring from its name */
1343 if (rte_ring_lookup("test") != r) {
1344 printf("Cannot lookup ring from its name\n");
1348 /* burst operations */
1349 if (test_ring_burst_basic() < 0)
1352 /* basic operations */
1353 if (test_ring_basic() < 0)
1357 if (test_ring_stats() < 0)
1360 /* basic operations */
1361 if (test_live_watermark_change() < 0)
1364 if ( test_set_watermark() < 0){
1365 printf ("Test failed to detect invalid parameter\n");
1369 printf ( "Test detected forced bad watermark values\n");
1371 if ( test_create_count_odd() < 0){
1372 printf ("Test failed to detect odd count\n");
1376 printf ( "Test detected odd count\n");
1378 if ( test_lookup_null() < 0){
1379 printf ("Test failed to detect NULL ring lookup\n");
1383 printf ( "Test detected NULL ring lookup \n");
1385 /* test of creating ring with wrong size */
1386 if (test_ring_creation_with_wrong_size() < 0)
1389 /* test of creation ring with an used name */
1390 if (test_ring_creation_with_an_used_name() < 0)
1393 /* dump the ring status */
1394 rte_ring_list_dump();