sleep in control plane thread
[dpdk.git] / app / test / test_ring.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <string.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #include <errno.h>
12 #include <sys/queue.h>
13
14 #include <rte_common.h>
15 #include <rte_log.h>
16 #include <rte_memory.h>
17 #include <rte_launch.h>
18 #include <rte_cycles.h>
19 #include <rte_eal.h>
20 #include <rte_per_lcore.h>
21 #include <rte_lcore.h>
22 #include <rte_atomic.h>
23 #include <rte_branch_prediction.h>
24 #include <rte_malloc.h>
25 #include <rte_ring.h>
26 #include <rte_ring_elem.h>
27 #include <rte_random.h>
28 #include <rte_errno.h>
29 #include <rte_hexdump.h>
30
31 #include "test.h"
32 #include "test_ring.h"
33
34 /*
35  * Ring
36  * ====
37  *
38  * #. Functional tests. Tests single/bulk/burst, default/SPSC/MPMC,
39  *    legacy/custom element size (4B, 8B, 16B, 20B) APIs.
40  *    Some tests incorporate unaligned addresses for objects.
41  *    The enqueued/dequeued data is validated for correctness.
42  *
43  * #. Performance tests are in test_ring_perf.c
44  */
45
46 #define RING_SIZE 4096
47 #define MAX_BULK 32
48
49 #define TEST_RING_VERIFY(exp)                                           \
50         if (!(exp)) {                                                   \
51                 printf("error at %s:%d\tcondition " #exp " failed\n",   \
52                     __func__, __LINE__);                                \
53                 rte_ring_dump(stdout, r);                               \
54                 return -1;                                              \
55         }
56
57 #define TEST_RING_FULL_EMTPY_ITER       8
58
59 static const int esize[] = {-1, 4, 8, 16, 20};
60
61 static void**
62 test_ring_inc_ptr(void **obj, int esize, unsigned int n)
63 {
64         /* Legacy queue APIs? */
65         if ((esize) == -1)
66                 return ((void **)obj) + n;
67         else
68                 return (void **)(((uint32_t *)obj) +
69                                         (n * esize / sizeof(uint32_t)));
70 }
71
72 static void
73 test_ring_mem_init(void *obj, unsigned int count, int esize)
74 {
75         unsigned int i;
76
77         /* Legacy queue APIs? */
78         if (esize == -1)
79                 for (i = 0; i < count; i++)
80                         ((void **)obj)[i] = (void *)(unsigned long)i;
81         else
82                 for (i = 0; i < (count * esize / sizeof(uint32_t)); i++)
83                         ((uint32_t *)obj)[i] = i;
84 }
85
86 static void
87 test_ring_print_test_string(const char *istr, unsigned int api_type, int esize)
88 {
89         printf("\n%s: ", istr);
90
91         if (esize == -1)
92                 printf("legacy APIs: ");
93         else
94                 printf("elem APIs: element size %dB ", esize);
95
96         if (api_type == TEST_RING_IGNORE_API_TYPE)
97                 return;
98
99         if (api_type & TEST_RING_THREAD_DEF)
100                 printf(": default enqueue/dequeue: ");
101         else if (api_type & TEST_RING_THREAD_SPSC)
102                 printf(": SP/SC: ");
103         else if (api_type & TEST_RING_THREAD_MPMC)
104                 printf(": MP/MC: ");
105
106         if (api_type & TEST_RING_ELEM_SINGLE)
107                 printf("single\n");
108         else if (api_type & TEST_RING_ELEM_BULK)
109                 printf("bulk\n");
110         else if (api_type & TEST_RING_ELEM_BURST)
111                 printf("burst\n");
112 }
113
114 /*
115  * Various negative test cases.
116  */
117 static int
118 test_ring_negative_tests(void)
119 {
120         struct rte_ring *rp = NULL;
121         struct rte_ring *rt = NULL;
122         unsigned int i;
123
124         /* Test with esize not a multiple of 4 */
125         rp = test_ring_create("test_bad_element_size", 23,
126                                 RING_SIZE + 1, SOCKET_ID_ANY, 0);
127         if (rp != NULL) {
128                 printf("Test failed to detect invalid element size\n");
129                 goto test_fail;
130         }
131
132
133         for (i = 0; i < RTE_DIM(esize); i++) {
134                 /* Test if ring size is not power of 2 */
135                 rp = test_ring_create("test_bad_ring_size", esize[i],
136                                         RING_SIZE + 1, SOCKET_ID_ANY, 0);
137                 if (rp != NULL) {
138                         printf("Test failed to detect odd count\n");
139                         goto test_fail;
140                 }
141
142                 /* Test if ring size is exceeding the limit */
143                 rp = test_ring_create("test_bad_ring_size", esize[i],
144                                         RTE_RING_SZ_MASK + 1, SOCKET_ID_ANY, 0);
145                 if (rp != NULL) {
146                         printf("Test failed to detect limits\n");
147                         goto test_fail;
148                 }
149
150                 /* Tests if lookup returns NULL on non-existing ring */
151                 rp = rte_ring_lookup("ring_not_found");
152                 if (rp != NULL && rte_errno != ENOENT) {
153                         printf("Test failed to detect NULL ring lookup\n");
154                         goto test_fail;
155                 }
156
157                 /* Test to if a non-power of 2 count causes the create
158                  * function to fail correctly
159                  */
160                 rp = test_ring_create("test_ring_count", esize[i], 4097,
161                                         SOCKET_ID_ANY, 0);
162                 if (rp != NULL)
163                         goto test_fail;
164
165                 rp = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
166                                         SOCKET_ID_ANY,
167                                         RING_F_SP_ENQ | RING_F_SC_DEQ);
168                 if (rp == NULL) {
169                         printf("test_ring_negative fail to create ring\n");
170                         goto test_fail;
171                 }
172
173                 if (rte_ring_lookup("test_ring_negative") != rp)
174                         goto test_fail;
175
176                 if (rte_ring_empty(rp) != 1) {
177                         printf("test_ring_nagative ring is not empty but it should be\n");
178                         goto test_fail;
179                 }
180
181                 /* Tests if it would always fail to create ring with an used
182                  * ring name.
183                  */
184                 rt = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
185                                         SOCKET_ID_ANY, 0);
186                 if (rt != NULL)
187                         goto test_fail;
188
189                 rte_ring_free(rp);
190                 rp = NULL;
191         }
192
193         return 0;
194
195 test_fail:
196
197         rte_ring_free(rp);
198         return -1;
199 }
200
201 /*
202  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
203  * Random number of elements are enqueued and dequeued.
204  */
205 static int
206 test_ring_burst_bulk_tests1(unsigned int api_type)
207 {
208         struct rte_ring *r;
209         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
210         int ret;
211         unsigned int i, j;
212         int rand;
213         const unsigned int rsz = RING_SIZE - 1;
214
215         for (i = 0; i < RTE_DIM(esize); i++) {
216                 test_ring_print_test_string("Test standard ring", api_type,
217                                                 esize[i]);
218
219                 /* Create the ring */
220                 r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
221                                         RING_SIZE, SOCKET_ID_ANY, 0);
222
223                 /* alloc dummy object pointers */
224                 src = test_ring_calloc(RING_SIZE * 2, esize[i]);
225                 if (src == NULL)
226                         goto fail;
227                 test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
228                 cur_src = src;
229
230                 /* alloc some room for copied objects */
231                 dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
232                 if (dst == NULL)
233                         goto fail;
234                 cur_dst = dst;
235
236                 printf("Random full/empty test\n");
237
238                 for (j = 0; j != TEST_RING_FULL_EMTPY_ITER; j++) {
239                         /* random shift in the ring */
240                         rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
241                         printf("%s: iteration %u, random shift: %u;\n",
242                             __func__, i, rand);
243                         ret = test_ring_enqueue(r, cur_src, esize[i], rand,
244                                                         api_type);
245                         TEST_RING_VERIFY(ret != 0);
246
247                         ret = test_ring_dequeue(r, cur_dst, esize[i], rand,
248                                                         api_type);
249                         TEST_RING_VERIFY(ret == rand);
250
251                         /* fill the ring */
252                         ret = test_ring_enqueue(r, cur_src, esize[i], rsz,
253                                                         api_type);
254                         TEST_RING_VERIFY(ret != 0);
255
256                         TEST_RING_VERIFY(rte_ring_free_count(r) == 0);
257                         TEST_RING_VERIFY(rsz == rte_ring_count(r));
258                         TEST_RING_VERIFY(rte_ring_full(r));
259                         TEST_RING_VERIFY(rte_ring_empty(r) == 0);
260
261                         /* empty the ring */
262                         ret = test_ring_dequeue(r, cur_dst, esize[i], rsz,
263                                                         api_type);
264                         TEST_RING_VERIFY(ret == (int)rsz);
265                         TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
266                         TEST_RING_VERIFY(rte_ring_count(r) == 0);
267                         TEST_RING_VERIFY(rte_ring_full(r) == 0);
268                         TEST_RING_VERIFY(rte_ring_empty(r));
269
270                         /* check data */
271                         TEST_RING_VERIFY(memcmp(src, dst, rsz) == 0);
272                 }
273
274                 /* Free memory before test completed */
275                 rte_ring_free(r);
276                 rte_free(src);
277                 rte_free(dst);
278                 r = NULL;
279                 src = NULL;
280                 dst = NULL;
281         }
282
283         return 0;
284 fail:
285         rte_ring_free(r);
286         rte_free(src);
287         rte_free(dst);
288         return -1;
289 }
290
291 /*
292  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
293  * Sequence of simple enqueues/dequeues and validate the enqueued and
294  * dequeued data.
295  */
296 static int
297 test_ring_burst_bulk_tests2(unsigned int api_type)
298 {
299         struct rte_ring *r;
300         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
301         int ret;
302         unsigned int i;
303
304         for (i = 0; i < RTE_DIM(esize); i++) {
305                 test_ring_print_test_string("Test standard ring", api_type,
306                                                 esize[i]);
307
308                 /* Create the ring */
309                 r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
310                                         RING_SIZE, SOCKET_ID_ANY, 0);
311
312                 /* alloc dummy object pointers */
313                 src = test_ring_calloc(RING_SIZE * 2, esize[i]);
314                 if (src == NULL)
315                         goto fail;
316                 test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
317                 cur_src = src;
318
319                 /* alloc some room for copied objects */
320                 dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
321                 if (dst == NULL)
322                         goto fail;
323                 cur_dst = dst;
324
325                 printf("enqueue 1 obj\n");
326                 ret = test_ring_enqueue(r, cur_src, esize[i], 1, api_type);
327                 if (ret != 1)
328                         goto fail;
329                 cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
330
331                 printf("enqueue 2 objs\n");
332                 ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type);
333                 if (ret != 2)
334                         goto fail;
335                 cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
336
337                 printf("enqueue MAX_BULK objs\n");
338                 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
339                                                 api_type);
340                 if (ret != MAX_BULK)
341                         goto fail;
342                 cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK);
343
344                 printf("dequeue 1 obj\n");
345                 ret = test_ring_dequeue(r, cur_dst, esize[i], 1, api_type);
346                 if (ret != 1)
347                         goto fail;
348                 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
349
350                 printf("dequeue 2 objs\n");
351                 ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type);
352                 if (ret != 2)
353                         goto fail;
354                 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
355
356                 printf("dequeue MAX_BULK objs\n");
357                 ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
358                                                 api_type);
359                 if (ret != MAX_BULK)
360                         goto fail;
361                 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK);
362
363                 /* check data */
364                 if (memcmp(src, dst, cur_dst - dst)) {
365                         rte_hexdump(stdout, "src", src, cur_src - src);
366                         rte_hexdump(stdout, "dst", dst, cur_dst - dst);
367                         printf("data after dequeue is not the same\n");
368                         goto fail;
369                 }
370
371                 /* Free memory before test completed */
372                 rte_ring_free(r);
373                 rte_free(src);
374                 rte_free(dst);
375                 r = NULL;
376                 src = NULL;
377                 dst = NULL;
378         }
379
380         return 0;
381 fail:
382         rte_ring_free(r);
383         rte_free(src);
384         rte_free(dst);
385         return -1;
386 }
387
388 /*
389  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
390  * Enqueue and dequeue to cover the entire ring length.
391  */
392 static int
393 test_ring_burst_bulk_tests3(unsigned int api_type)
394 {
395         struct rte_ring *r;
396         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
397         int ret;
398         unsigned int i, j;
399
400         for (i = 0; i < RTE_DIM(esize); i++) {
401                 test_ring_print_test_string("Test standard ring", api_type,
402                                                 esize[i]);
403
404                 /* Create the ring */
405                 r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
406                                         RING_SIZE, SOCKET_ID_ANY, 0);
407
408                 /* alloc dummy object pointers */
409                 src = test_ring_calloc(RING_SIZE * 2, esize[i]);
410                 if (src == NULL)
411                         goto fail;
412                 test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
413                 cur_src = src;
414
415                 /* alloc some room for copied objects */
416                 dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
417                 if (dst == NULL)
418                         goto fail;
419                 cur_dst = dst;
420
421                 printf("fill and empty the ring\n");
422                 for (j = 0; j < RING_SIZE / MAX_BULK; j++) {
423                         ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
424                                                         api_type);
425                         if (ret != MAX_BULK)
426                                 goto fail;
427                         cur_src = test_ring_inc_ptr(cur_src, esize[i],
428                                                                 MAX_BULK);
429
430                         ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
431                                                         api_type);
432                         if (ret != MAX_BULK)
433                                 goto fail;
434                         cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
435                                                                 MAX_BULK);
436                 }
437
438                 /* check data */
439                 if (memcmp(src, dst, cur_dst - dst)) {
440                         rte_hexdump(stdout, "src", src, cur_src - src);
441                         rte_hexdump(stdout, "dst", dst, cur_dst - dst);
442                         printf("data after dequeue is not the same\n");
443                         goto fail;
444                 }
445
446                 /* Free memory before test completed */
447                 rte_ring_free(r);
448                 rte_free(src);
449                 rte_free(dst);
450                 r = NULL;
451                 src = NULL;
452                 dst = NULL;
453         }
454
455         return 0;
456 fail:
457         rte_ring_free(r);
458         rte_free(src);
459         rte_free(dst);
460         return -1;
461 }
462
463 /*
464  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
465  * Enqueue till the ring is full and dequeue till the ring becomes empty.
466  */
467 static int
468 test_ring_burst_bulk_tests4(unsigned int api_type)
469 {
470         struct rte_ring *r;
471         void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
472         int ret;
473         unsigned int i, j;
474         unsigned int num_elems;
475
476         for (i = 0; i < RTE_DIM(esize); i++) {
477                 test_ring_print_test_string("Test standard ring", api_type,
478                                                 esize[i]);
479
480                 /* Create the ring */
481                 r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
482                                         RING_SIZE, SOCKET_ID_ANY, 0);
483
484                 /* alloc dummy object pointers */
485                 src = test_ring_calloc(RING_SIZE * 2, esize[i]);
486                 if (src == NULL)
487                         goto fail;
488                 test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
489                 cur_src = src;
490
491                 /* alloc some room for copied objects */
492                 dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
493                 if (dst == NULL)
494                         goto fail;
495                 cur_dst = dst;
496
497                 printf("Test enqueue without enough memory space\n");
498                 for (j = 0; j < (RING_SIZE/MAX_BULK - 1); j++) {
499                         ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
500                                                         api_type);
501                         if (ret != MAX_BULK)
502                                 goto fail;
503                         cur_src = test_ring_inc_ptr(cur_src, esize[i],
504                                                                 MAX_BULK);
505                 }
506
507                 printf("Enqueue 2 objects, free entries = MAX_BULK - 2\n");
508                 ret = test_ring_enqueue(r, cur_src, esize[i], 2, api_type);
509                 if (ret != 2)
510                         goto fail;
511                 cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
512
513                 printf("Enqueue the remaining entries = MAX_BULK - 3\n");
514                 /* Bulk APIs enqueue exact number of elements */
515                 if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
516                         num_elems = MAX_BULK - 3;
517                 else
518                         num_elems = MAX_BULK;
519                 /* Always one free entry left */
520                 ret = test_ring_enqueue(r, cur_src, esize[i], num_elems,
521                                                 api_type);
522                 if (ret != MAX_BULK - 3)
523                         goto fail;
524                 cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK - 3);
525
526                 printf("Test if ring is full\n");
527                 if (rte_ring_full(r) != 1)
528                         goto fail;
529
530                 printf("Test enqueue for a full entry\n");
531                 ret = test_ring_enqueue(r, cur_src, esize[i], MAX_BULK,
532                                                 api_type);
533                 if (ret != 0)
534                         goto fail;
535
536                 printf("Test dequeue without enough objects\n");
537                 for (j = 0; j < RING_SIZE / MAX_BULK - 1; j++) {
538                         ret = test_ring_dequeue(r, cur_dst, esize[i], MAX_BULK,
539                                                         api_type);
540                         if (ret != MAX_BULK)
541                                 goto fail;
542                         cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
543                                                                 MAX_BULK);
544                 }
545
546                 /* Available memory space for the exact MAX_BULK entries */
547                 ret = test_ring_dequeue(r, cur_dst, esize[i], 2, api_type);
548                 if (ret != 2)
549                         goto fail;
550                 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
551
552                 /* Bulk APIs enqueue exact number of elements */
553                 if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
554                         num_elems = MAX_BULK - 3;
555                 else
556                         num_elems = MAX_BULK;
557                 ret = test_ring_dequeue(r, cur_dst, esize[i], num_elems,
558                                                 api_type);
559                 if (ret != MAX_BULK - 3)
560                         goto fail;
561                 cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK - 3);
562
563                 printf("Test if ring is empty\n");
564                 /* Check if ring is empty */
565                 if (rte_ring_empty(r) != 1)
566                         goto fail;
567
568                 /* check data */
569                 if (memcmp(src, dst, cur_dst - dst)) {
570                         rte_hexdump(stdout, "src", src, cur_src - src);
571                         rte_hexdump(stdout, "dst", dst, cur_dst - dst);
572                         printf("data after dequeue is not the same\n");
573                         goto fail;
574                 }
575
576                 /* Free memory before test completed */
577                 rte_ring_free(r);
578                 rte_free(src);
579                 rte_free(dst);
580                 r = NULL;
581                 src = NULL;
582                 dst = NULL;
583         }
584
585         return 0;
586 fail:
587         rte_ring_free(r);
588         rte_free(src);
589         rte_free(dst);
590         return -1;
591 }
592
593 /*
594  * Test default, single element, bulk and burst APIs
595  */
596 static int
597 test_ring_basic_ex(void)
598 {
599         int ret = -1;
600         unsigned int i, j;
601         struct rte_ring *rp = NULL;
602         void *obj = NULL;
603
604         for (i = 0; i < RTE_DIM(esize); i++) {
605                 obj = test_ring_calloc(RING_SIZE, esize[i]);
606                 if (obj == NULL) {
607                         printf("%s: failed to alloc memory\n", __func__);
608                         goto fail_test;
609                 }
610
611                 rp = test_ring_create("test_ring_basic_ex", esize[i], RING_SIZE,
612                                         SOCKET_ID_ANY,
613                                         RING_F_SP_ENQ | RING_F_SC_DEQ);
614                 if (rp == NULL) {
615                         printf("%s: failed to create ring\n", __func__);
616                         goto fail_test;
617                 }
618
619                 if (rte_ring_lookup("test_ring_basic_ex") != rp) {
620                         printf("%s: failed to find ring\n", __func__);
621                         goto fail_test;
622                 }
623
624                 if (rte_ring_empty(rp) != 1) {
625                         printf("%s: ring is not empty but it should be\n",
626                                 __func__);
627                         goto fail_test;
628                 }
629
630                 printf("%u ring entries are now free\n",
631                         rte_ring_free_count(rp));
632
633                 for (j = 0; j < RING_SIZE; j++) {
634                         test_ring_enqueue(rp, obj, esize[i], 1,
635                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
636                 }
637
638                 if (rte_ring_full(rp) != 1) {
639                         printf("%s: ring is not full but it should be\n",
640                                 __func__);
641                         goto fail_test;
642                 }
643
644                 for (j = 0; j < RING_SIZE; j++) {
645                         test_ring_dequeue(rp, obj, esize[i], 1,
646                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
647                 }
648
649                 if (rte_ring_empty(rp) != 1) {
650                         printf("%s: ring is not empty but it should be\n",
651                                 __func__);
652                         goto fail_test;
653                 }
654
655                 /* Following tests use the configured flags to decide
656                  * SP/SC or MP/MC.
657                  */
658                 /* Covering the ring burst operation */
659                 ret = test_ring_enqueue(rp, obj, esize[i], 2,
660                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
661                 if (ret != 2) {
662                         printf("%s: rte_ring_enqueue_burst fails\n", __func__);
663                         goto fail_test;
664                 }
665
666                 ret = test_ring_dequeue(rp, obj, esize[i], 2,
667                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
668                 if (ret != 2) {
669                         printf("%s: rte_ring_dequeue_burst fails\n", __func__);
670                         goto fail_test;
671                 }
672
673                 /* Covering the ring bulk operation */
674                 ret = test_ring_enqueue(rp, obj, esize[i], 2,
675                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
676                 if (ret != 2) {
677                         printf("%s: rte_ring_enqueue_bulk fails\n", __func__);
678                         goto fail_test;
679                 }
680
681                 ret = test_ring_dequeue(rp, obj, esize[i], 2,
682                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
683                 if (ret != 2) {
684                         printf("%s: rte_ring_dequeue_bulk fails\n", __func__);
685                         goto fail_test;
686                 }
687
688                 rte_ring_free(rp);
689                 rte_free(obj);
690                 rp = NULL;
691                 obj = NULL;
692         }
693
694         return 0;
695
696 fail_test:
697         rte_ring_free(rp);
698         if (obj != NULL)
699                 rte_free(obj);
700
701         return -1;
702 }
703
704 /*
705  * Basic test cases with exact size ring.
706  */
707 static int
708 test_ring_with_exact_size(void)
709 {
710         struct rte_ring *std_r = NULL, *exact_sz_r = NULL;
711         void *obj_orig;
712         void *obj;
713         const unsigned int ring_sz = 16;
714         unsigned int i, j;
715         int ret = -1;
716
717         for (i = 0; i < RTE_DIM(esize); i++) {
718                 test_ring_print_test_string("Test exact size ring",
719                                 TEST_RING_IGNORE_API_TYPE,
720                                 esize[i]);
721
722                 /* alloc object pointers. Allocate one extra object
723                  * and create an unaligned address.
724                  */
725                 obj_orig = test_ring_calloc(17, esize[i]);
726                 if (obj_orig == NULL)
727                         goto test_fail;
728                 obj = ((char *)obj_orig) + 1;
729
730                 std_r = test_ring_create("std", esize[i], ring_sz,
731                                         rte_socket_id(),
732                                         RING_F_SP_ENQ | RING_F_SC_DEQ);
733                 if (std_r == NULL) {
734                         printf("%s: error, can't create std ring\n", __func__);
735                         goto test_fail;
736                 }
737                 exact_sz_r = test_ring_create("exact sz", esize[i], ring_sz,
738                                 rte_socket_id(),
739                                 RING_F_SP_ENQ | RING_F_SC_DEQ |
740                                 RING_F_EXACT_SZ);
741                 if (exact_sz_r == NULL) {
742                         printf("%s: error, can't create exact size ring\n",
743                                         __func__);
744                         goto test_fail;
745                 }
746
747                 /*
748                  * Check that the exact size ring is bigger than the
749                  * standard ring
750                  */
751                 if (rte_ring_get_size(std_r) >= rte_ring_get_size(exact_sz_r)) {
752                         printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n",
753                                         __func__,
754                                         rte_ring_get_size(std_r),
755                                         rte_ring_get_size(exact_sz_r));
756                         goto test_fail;
757                 }
758                 /*
759                  * check that the exact_sz_ring can hold one more element
760                  * than the standard ring. (16 vs 15 elements)
761                  */
762                 for (j = 0; j < ring_sz - 1; j++) {
763                         test_ring_enqueue(std_r, obj, esize[i], 1,
764                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
765                         test_ring_enqueue(exact_sz_r, obj, esize[i], 1,
766                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
767                 }
768                 ret = test_ring_enqueue(std_r, obj, esize[i], 1,
769                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
770                 if (ret != -ENOBUFS) {
771                         printf("%s: error, unexpected successful enqueue\n",
772                                 __func__);
773                         goto test_fail;
774                 }
775                 ret = test_ring_enqueue(exact_sz_r, obj, esize[i], 1,
776                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
777                 if (ret == -ENOBUFS) {
778                         printf("%s: error, enqueue failed\n", __func__);
779                         goto test_fail;
780                 }
781
782                 /* check that dequeue returns the expected number of elements */
783                 ret = test_ring_dequeue(exact_sz_r, obj, esize[i], ring_sz,
784                                 TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
785                 if (ret != (int)ring_sz) {
786                         printf("%s: error, failed to dequeue expected nb of elements\n",
787                                 __func__);
788                         goto test_fail;
789                 }
790
791                 /* check that the capacity function returns expected value */
792                 if (rte_ring_get_capacity(exact_sz_r) != ring_sz) {
793                         printf("%s: error, incorrect ring capacity reported\n",
794                                         __func__);
795                         goto test_fail;
796                 }
797
798                 rte_free(obj_orig);
799                 rte_ring_free(std_r);
800                 rte_ring_free(exact_sz_r);
801                 obj_orig = NULL;
802                 std_r = NULL;
803                 exact_sz_r = NULL;
804         }
805
806         return 0;
807
808 test_fail:
809         rte_free(obj_orig);
810         rte_ring_free(std_r);
811         rte_ring_free(exact_sz_r);
812         return -1;
813 }
814
815 static int
816 test_ring(void)
817 {
818         unsigned int i, j;
819
820         /* Negative test cases */
821         if (test_ring_negative_tests() < 0)
822                 goto test_fail;
823
824         /* Some basic operations */
825         if (test_ring_basic_ex() < 0)
826                 goto test_fail;
827
828         if (test_ring_with_exact_size() < 0)
829                 goto test_fail;
830
831         /* Burst and bulk operations with sp/sc, mp/mc and default.
832          * The test cases are split into smaller test cases to
833          * help clang compile faster.
834          */
835         for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
836                 for (i = TEST_RING_THREAD_DEF;
837                                         i <= TEST_RING_THREAD_MPMC; i <<= 1)
838                         if (test_ring_burst_bulk_tests1(i | j) < 0)
839                                 goto test_fail;
840
841         for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
842                 for (i = TEST_RING_THREAD_DEF;
843                                         i <= TEST_RING_THREAD_MPMC; i <<= 1)
844                         if (test_ring_burst_bulk_tests2(i | j) < 0)
845                                 goto test_fail;
846
847         for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
848                 for (i = TEST_RING_THREAD_DEF;
849                                         i <= TEST_RING_THREAD_MPMC; i <<= 1)
850                         if (test_ring_burst_bulk_tests3(i | j) < 0)
851                                 goto test_fail;
852
853         for (j = TEST_RING_ELEM_BULK; j <= TEST_RING_ELEM_BURST; j <<= 1)
854                 for (i = TEST_RING_THREAD_DEF;
855                                         i <= TEST_RING_THREAD_MPMC; i <<= 1)
856                         if (test_ring_burst_bulk_tests4(i | j) < 0)
857                                 goto test_fail;
858
859         /* dump the ring status */
860         rte_ring_list_dump(stdout);
861
862         return 0;
863
864 test_fail:
865
866         return -1;
867 }
868
869 REGISTER_TEST_COMMAND(ring_autotest, test_ring);