Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : * Copyright(c) 2020 Arm Limited
4 : : */
5 : :
6 : : #include <string.h>
7 : : #include <stdarg.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <stdint.h>
11 : : #include <inttypes.h>
12 : : #include <errno.h>
13 : : #include <sys/queue.h>
14 : :
15 : : #include <rte_common.h>
16 : : #include <rte_log.h>
17 : : #include <rte_memory.h>
18 : : #include <rte_launch.h>
19 : : #include <rte_cycles.h>
20 : : #include <rte_eal.h>
21 : : #include <rte_per_lcore.h>
22 : : #include <rte_lcore.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 : : /*
50 : : * Validate the return value of test cases and print details of the
51 : : * ring if validation fails
52 : : *
53 : : * @param exp
54 : : * Expression to validate return value.
55 : : * @param r
56 : : * A pointer to the ring structure.
57 : : */
58 : : #define TEST_RING_VERIFY(exp, r, errst) do { \
59 : : if (!(exp)) { \
60 : : printf("error at %s:%d\tcondition " #exp " failed\n", \
61 : : __func__, __LINE__); \
62 : : rte_ring_dump(stdout, (r)); \
63 : : errst; \
64 : : } \
65 : : } while (0)
66 : :
67 : : #define TEST_RING_FULL_EMPTY_ITER 8
68 : :
69 : : static const int esize[] = {-1, 4, 8, 16, 20};
70 : :
71 : : /* Wrappers around the zero-copy APIs. The wrappers match
72 : : * the normal enqueue/dequeue API declarations.
73 : : */
74 : : static unsigned int
75 [ + + - ]: 554 : test_ring_enqueue_zc_bulk(struct rte_ring *r, void * const *obj_table,
76 : : unsigned int n, unsigned int *free_space)
77 : : {
78 : : uint32_t ret;
79 : : struct rte_ring_zc_data zcd;
80 : :
81 : : ret = rte_ring_enqueue_zc_bulk_start(r, n, &zcd, free_space);
82 [ + + ]: 554 : if (ret != 0) {
83 : : /* Copy the data to the ring */
84 : 552 : test_ring_copy_to(&zcd, obj_table, sizeof(void *), ret);
85 : : rte_ring_enqueue_zc_finish(r, ret);
86 : : }
87 : :
88 : 554 : return ret;
89 : : }
90 : :
91 : : static unsigned int
92 [ + + - ]: 2216 : test_ring_enqueue_zc_bulk_elem(struct rte_ring *r, const void *obj_table,
93 : : unsigned int esize, unsigned int n, unsigned int *free_space)
94 : : {
95 : : unsigned int ret;
96 : : struct rte_ring_zc_data zcd;
97 : :
98 : : ret = rte_ring_enqueue_zc_bulk_elem_start(r, esize, n,
99 : : &zcd, free_space);
100 [ + + ]: 2216 : if (ret != 0) {
101 : : /* Copy the data to the ring */
102 : 2208 : test_ring_copy_to(&zcd, obj_table, esize, ret);
103 : : rte_ring_enqueue_zc_finish(r, ret);
104 : : }
105 : :
106 : 2216 : return ret;
107 : : }
108 : :
109 : : static unsigned int
110 [ + + - ]: 554 : test_ring_enqueue_zc_burst(struct rte_ring *r, void * const *obj_table,
111 : : unsigned int n, unsigned int *free_space)
112 : : {
113 : : unsigned int ret;
114 : : struct rte_ring_zc_data zcd;
115 : :
116 : : ret = rte_ring_enqueue_zc_burst_start(r, n, &zcd, free_space);
117 [ + + ]: 554 : if (ret != 0) {
118 : : /* Copy the data to the ring */
119 : 552 : test_ring_copy_to(&zcd, obj_table, sizeof(void *), ret);
120 : : rte_ring_enqueue_zc_finish(r, ret);
121 : : }
122 : :
123 : 554 : return ret;
124 : : }
125 : :
126 : : static unsigned int
127 [ + + - ]: 2216 : test_ring_enqueue_zc_burst_elem(struct rte_ring *r, const void *obj_table,
128 : : unsigned int esize, unsigned int n, unsigned int *free_space)
129 : : {
130 : : unsigned int ret;
131 : : struct rte_ring_zc_data zcd;
132 : :
133 : : ret = rte_ring_enqueue_zc_burst_elem_start(r, esize, n,
134 : : &zcd, free_space);
135 [ + + ]: 2216 : if (ret != 0) {
136 : : /* Copy the data to the ring */
137 : 2208 : test_ring_copy_to(&zcd, obj_table, esize, ret);
138 : : rte_ring_enqueue_zc_finish(r, ret);
139 : : }
140 : :
141 : 2216 : return ret;
142 : : }
143 : :
144 : : static unsigned int
145 [ + + - ]: 552 : test_ring_dequeue_zc_bulk(struct rte_ring *r, void **obj_table,
146 : : unsigned int n, unsigned int *available)
147 : : {
148 : : unsigned int ret;
149 : : struct rte_ring_zc_data zcd;
150 : :
151 : : ret = rte_ring_dequeue_zc_bulk_start(r, n, &zcd, available);
152 [ + - ]: 552 : if (ret != 0) {
153 : : /* Copy the data from the ring */
154 : 552 : test_ring_copy_from(&zcd, obj_table, sizeof(void *), ret);
155 : : rte_ring_dequeue_zc_finish(r, ret);
156 : : }
157 : :
158 : 552 : return ret;
159 : : }
160 : :
161 : : static unsigned int
162 [ + + - ]: 2208 : test_ring_dequeue_zc_bulk_elem(struct rte_ring *r, void *obj_table,
163 : : unsigned int esize, unsigned int n, unsigned int *available)
164 : : {
165 : : unsigned int ret;
166 : : struct rte_ring_zc_data zcd;
167 : :
168 : : ret = rte_ring_dequeue_zc_bulk_elem_start(r, esize, n,
169 : : &zcd, available);
170 [ + - ]: 2208 : if (ret != 0) {
171 : : /* Copy the data from the ring */
172 : 2208 : test_ring_copy_from(&zcd, obj_table, esize, ret);
173 : : rte_ring_dequeue_zc_finish(r, ret);
174 : : }
175 : :
176 : 2208 : return ret;
177 : : }
178 : :
179 : : static unsigned int
180 [ + + - ]: 552 : test_ring_dequeue_zc_burst(struct rte_ring *r, void **obj_table,
181 : : unsigned int n, unsigned int *available)
182 : : {
183 : : unsigned int ret;
184 : : struct rte_ring_zc_data zcd;
185 : :
186 : : ret = rte_ring_dequeue_zc_burst_start(r, n, &zcd, available);
187 [ + - ]: 552 : if (ret != 0) {
188 : : /* Copy the data from the ring */
189 : 552 : test_ring_copy_from(&zcd, obj_table, sizeof(void *), ret);
190 : : rte_ring_dequeue_zc_finish(r, ret);
191 : : }
192 : :
193 : 552 : return ret;
194 : : }
195 : :
196 : : static unsigned int
197 [ + + - ]: 2208 : test_ring_dequeue_zc_burst_elem(struct rte_ring *r, void *obj_table,
198 : : unsigned int esize, unsigned int n, unsigned int *available)
199 : : {
200 : : unsigned int ret;
201 : : struct rte_ring_zc_data zcd;
202 : :
203 : : ret = rte_ring_dequeue_zc_burst_elem_start(r, esize, n,
204 : : &zcd, available);
205 [ + - ]: 2208 : if (ret != 0) {
206 : : /* Copy the data from the ring */
207 : 2208 : test_ring_copy_from(&zcd, obj_table, esize, ret);
208 : : rte_ring_dequeue_zc_finish(r, ret);
209 : : }
210 : :
211 : 2208 : return ret;
212 : : }
213 : :
214 : : static const struct {
215 : : const char *desc;
216 : : uint32_t api_type;
217 : : uint32_t create_flags;
218 : : struct {
219 : : unsigned int (*flegacy)(struct rte_ring *r,
220 : : void * const *obj_table, unsigned int n,
221 : : unsigned int *free_space);
222 : : unsigned int (*felem)(struct rte_ring *r, const void *obj_table,
223 : : unsigned int esize, unsigned int n,
224 : : unsigned int *free_space);
225 : : } enq;
226 : : struct {
227 : : unsigned int (*flegacy)(struct rte_ring *r,
228 : : void **obj_table, unsigned int n,
229 : : unsigned int *available);
230 : : unsigned int (*felem)(struct rte_ring *r, void *obj_table,
231 : : unsigned int esize, unsigned int n,
232 : : unsigned int *available);
233 : : } deq;
234 : : } test_enqdeq_impl[] = {
235 : : {
236 : : .desc = "MP/MC sync mode",
237 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
238 : : .create_flags = 0,
239 : : .enq = {
240 : : .flegacy = rte_ring_enqueue_bulk,
241 : : .felem = rte_ring_enqueue_bulk_elem,
242 : : },
243 : : .deq = {
244 : : .flegacy = rte_ring_dequeue_bulk,
245 : : .felem = rte_ring_dequeue_bulk_elem,
246 : : },
247 : : },
248 : : {
249 : : .desc = "SP/SC sync mode",
250 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_SPSC,
251 : : .create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
252 : : .enq = {
253 : : .flegacy = rte_ring_sp_enqueue_bulk,
254 : : .felem = rte_ring_sp_enqueue_bulk_elem,
255 : : },
256 : : .deq = {
257 : : .flegacy = rte_ring_sc_dequeue_bulk,
258 : : .felem = rte_ring_sc_dequeue_bulk_elem,
259 : : },
260 : : },
261 : : {
262 : : .desc = "MP/MC sync mode",
263 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_MPMC,
264 : : .create_flags = 0,
265 : : .enq = {
266 : : .flegacy = rte_ring_mp_enqueue_bulk,
267 : : .felem = rte_ring_mp_enqueue_bulk_elem,
268 : : },
269 : : .deq = {
270 : : .flegacy = rte_ring_mc_dequeue_bulk,
271 : : .felem = rte_ring_mc_dequeue_bulk_elem,
272 : : },
273 : : },
274 : : {
275 : : .desc = "MP_RTS/MC_RTS sync mode",
276 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
277 : : .create_flags = RING_F_MP_RTS_ENQ | RING_F_MC_RTS_DEQ,
278 : : .enq = {
279 : : .flegacy = rte_ring_enqueue_bulk,
280 : : .felem = rte_ring_enqueue_bulk_elem,
281 : : },
282 : : .deq = {
283 : : .flegacy = rte_ring_dequeue_bulk,
284 : : .felem = rte_ring_dequeue_bulk_elem,
285 : : },
286 : : },
287 : : {
288 : : .desc = "MP_HTS/MC_HTS sync mode",
289 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
290 : : .create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
291 : : .enq = {
292 : : .flegacy = rte_ring_enqueue_bulk,
293 : : .felem = rte_ring_enqueue_bulk_elem,
294 : : },
295 : : .deq = {
296 : : .flegacy = rte_ring_dequeue_bulk,
297 : : .felem = rte_ring_dequeue_bulk_elem,
298 : : },
299 : : },
300 : : {
301 : : .desc = "MP/MC sync mode",
302 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
303 : : .create_flags = 0,
304 : : .enq = {
305 : : .flegacy = rte_ring_enqueue_burst,
306 : : .felem = rte_ring_enqueue_burst_elem,
307 : : },
308 : : .deq = {
309 : : .flegacy = rte_ring_dequeue_burst,
310 : : .felem = rte_ring_dequeue_burst_elem,
311 : : },
312 : : },
313 : : {
314 : : .desc = "SP/SC sync mode",
315 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_SPSC,
316 : : .create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
317 : : .enq = {
318 : : .flegacy = rte_ring_sp_enqueue_burst,
319 : : .felem = rte_ring_sp_enqueue_burst_elem,
320 : : },
321 : : .deq = {
322 : : .flegacy = rte_ring_sc_dequeue_burst,
323 : : .felem = rte_ring_sc_dequeue_burst_elem,
324 : : },
325 : : },
326 : : {
327 : : .desc = "MP/MC sync mode",
328 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_MPMC,
329 : : .create_flags = 0,
330 : : .enq = {
331 : : .flegacy = rte_ring_mp_enqueue_burst,
332 : : .felem = rte_ring_mp_enqueue_burst_elem,
333 : : },
334 : : .deq = {
335 : : .flegacy = rte_ring_mc_dequeue_burst,
336 : : .felem = rte_ring_mc_dequeue_burst_elem,
337 : : },
338 : : },
339 : : {
340 : : .desc = "MP_RTS/MC_RTS sync mode",
341 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
342 : : .create_flags = RING_F_MP_RTS_ENQ | RING_F_MC_RTS_DEQ,
343 : : .enq = {
344 : : .flegacy = rte_ring_enqueue_burst,
345 : : .felem = rte_ring_enqueue_burst_elem,
346 : : },
347 : : .deq = {
348 : : .flegacy = rte_ring_dequeue_burst,
349 : : .felem = rte_ring_dequeue_burst_elem,
350 : : },
351 : : },
352 : : {
353 : : .desc = "MP_HTS/MC_HTS sync mode",
354 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
355 : : .create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
356 : : .enq = {
357 : : .flegacy = rte_ring_enqueue_burst,
358 : : .felem = rte_ring_enqueue_burst_elem,
359 : : },
360 : : .deq = {
361 : : .flegacy = rte_ring_dequeue_burst,
362 : : .felem = rte_ring_dequeue_burst_elem,
363 : : },
364 : : },
365 : : {
366 : : .desc = "SP/SC sync mode (ZC)",
367 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_SPSC,
368 : : .create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
369 : : .enq = {
370 : : .flegacy = test_ring_enqueue_zc_bulk,
371 : : .felem = test_ring_enqueue_zc_bulk_elem,
372 : : },
373 : : .deq = {
374 : : .flegacy = test_ring_dequeue_zc_bulk,
375 : : .felem = test_ring_dequeue_zc_bulk_elem,
376 : : },
377 : : },
378 : : {
379 : : .desc = "MP_HTS/MC_HTS sync mode (ZC)",
380 : : .api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
381 : : .create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
382 : : .enq = {
383 : : .flegacy = test_ring_enqueue_zc_bulk,
384 : : .felem = test_ring_enqueue_zc_bulk_elem,
385 : : },
386 : : .deq = {
387 : : .flegacy = test_ring_dequeue_zc_bulk,
388 : : .felem = test_ring_dequeue_zc_bulk_elem,
389 : : },
390 : : },
391 : : {
392 : : .desc = "SP/SC sync mode (ZC)",
393 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_SPSC,
394 : : .create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
395 : : .enq = {
396 : : .flegacy = test_ring_enqueue_zc_burst,
397 : : .felem = test_ring_enqueue_zc_burst_elem,
398 : : },
399 : : .deq = {
400 : : .flegacy = test_ring_dequeue_zc_burst,
401 : : .felem = test_ring_dequeue_zc_burst_elem,
402 : : },
403 : : },
404 : : {
405 : : .desc = "MP_HTS/MC_HTS sync mode (ZC)",
406 : : .api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
407 : : .create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
408 : : .enq = {
409 : : .flegacy = test_ring_enqueue_zc_burst,
410 : : .felem = test_ring_enqueue_zc_burst_elem,
411 : : },
412 : : .deq = {
413 : : .flegacy = test_ring_dequeue_zc_burst,
414 : : .felem = test_ring_dequeue_zc_burst_elem,
415 : : },
416 : : }
417 : : };
418 : :
419 : : static unsigned int
420 : 19390 : test_ring_enq_impl(struct rte_ring *r, void **obj, int esize, unsigned int n,
421 : : unsigned int test_idx)
422 : : {
423 [ + + ]: 19390 : if (esize == -1)
424 : 3878 : return test_enqdeq_impl[test_idx].enq.flegacy(r, obj, n, NULL);
425 : : else
426 : 15512 : return test_enqdeq_impl[test_idx].enq.felem(r, obj, esize, n,
427 : : NULL);
428 : : }
429 : :
430 : : static unsigned int
431 : 19320 : test_ring_deq_impl(struct rte_ring *r, void **obj, int esize, unsigned int n,
432 : : unsigned int test_idx)
433 : : {
434 [ + + ]: 19320 : if (esize == -1)
435 : 3864 : return test_enqdeq_impl[test_idx].deq.flegacy(r, obj, n, NULL);
436 : : else
437 : 15456 : return test_enqdeq_impl[test_idx].deq.felem(r, obj, esize, n,
438 : : NULL);
439 : : }
440 : :
441 : : static void
442 : : test_ring_mem_init(void *obj, unsigned int count, int esize)
443 : : {
444 : : unsigned int i;
445 : :
446 : : /* Legacy queue APIs? */
447 [ + + + + : 290 : if (esize == -1)
+ + + + +
+ + + ]
448 [ + + + + : 462923 : for (i = 0; i < count; i++)
+ + + + +
+ + + ]
449 : 462865 : ((void **)obj)[i] = (void *)(uintptr_t)i;
450 : : else
451 [ + + + + : 5554612 : for (i = 0; i < (count * esize / sizeof(uint32_t)); i++)
+ + + + +
+ + + ]
452 : 5554380 : ((uint32_t *)obj)[i] = i;
453 : : }
454 : :
455 : : static int
456 : 785 : test_ring_mem_cmp(void *src, void *dst, unsigned int size)
457 : : {
458 : : int ret;
459 : :
460 : 785 : ret = memcmp(src, dst, size);
461 [ - + ]: 785 : if (ret) {
462 : 0 : rte_hexdump(stdout, "src", src, size);
463 : 0 : rte_hexdump(stdout, "dst", dst, size);
464 : : printf("data after dequeue is not the same\n");
465 : : }
466 : :
467 : 785 : return ret;
468 : : }
469 : :
470 : : static void
471 : 285 : test_ring_print_test_string(const char *istr, unsigned int api_type, int esize)
472 : : {
473 : : printf("\n%s: ", istr);
474 : :
475 [ + + ]: 285 : if (esize == -1)
476 : : printf("legacy APIs: ");
477 : : else
478 : : printf("elem APIs: element size %dB ", esize);
479 : :
480 [ + + ]: 285 : if (api_type == TEST_RING_IGNORE_API_TYPE)
481 : : return;
482 : :
483 [ + + ]: 280 : if (api_type & TEST_RING_THREAD_DEF)
484 : : printf(": default enqueue/dequeue: ");
485 [ + + ]: 120 : else if (api_type & TEST_RING_THREAD_SPSC)
486 : : printf(": SP/SC: ");
487 [ + - ]: 40 : else if (api_type & TEST_RING_THREAD_MPMC)
488 : : printf(": MP/MC: ");
489 : :
490 [ - + ]: 280 : if (api_type & TEST_RING_ELEM_SINGLE)
491 : : printf("single\n");
492 [ + + ]: 280 : else if (api_type & TEST_RING_ELEM_BULK)
493 : : printf("bulk\n");
494 [ + - ]: 140 : else if (api_type & TEST_RING_ELEM_BURST)
495 : : printf("burst\n");
496 : : }
497 : :
498 : : /*
499 : : * Various negative test cases.
500 : : */
501 : : static int
502 : 1 : test_ring_negative_tests(void)
503 : : {
504 : : struct rte_ring *rp = NULL;
505 : : struct rte_ring *rt = NULL;
506 : : unsigned int i;
507 : :
508 : : /* Test zero size ring */
509 : : rp = test_ring_create("test_zero_size_ring", -1, 0, SOCKET_ID_ANY, 0);
510 [ - + ]: 1 : if (rp != NULL) {
511 : : printf("Test failed to detect zero size ring\n");
512 : 0 : goto test_fail;
513 : : }
514 : :
515 : : /* Test with esize not a multiple of 4 */
516 : : rp = test_ring_create("test_bad_element_size", 23,
517 : : RING_SIZE + 1, SOCKET_ID_ANY, 0);
518 [ + - ]: 1 : if (rp != NULL) {
519 : : printf("Test failed to detect invalid element size\n");
520 : 0 : goto test_fail;
521 : : }
522 : :
523 : :
524 [ + + ]: 6 : for (i = 0; i < RTE_DIM(esize); i++) {
525 : : /* Test if ring size is not power of 2 */
526 : 5 : rp = test_ring_create("test_bad_ring_size", esize[i],
527 : : RING_SIZE + 1, SOCKET_ID_ANY, 0);
528 [ - + ]: 5 : if (rp != NULL) {
529 : : printf("Test failed to detect odd count\n");
530 : 0 : goto test_fail;
531 : : }
532 : :
533 : : /* Test if ring size is exceeding the limit */
534 : 5 : rp = test_ring_create("test_bad_ring_size", esize[i],
535 : : RTE_RING_SZ_MASK + 1, SOCKET_ID_ANY, 0);
536 [ - + ]: 5 : if (rp != NULL) {
537 : : printf("Test failed to detect limits\n");
538 : 0 : goto test_fail;
539 : : }
540 : :
541 : : /* Tests if lookup returns NULL on non-existing ring */
542 : 5 : rp = rte_ring_lookup("ring_not_found");
543 [ - + - - ]: 5 : if (rp != NULL && rte_errno != ENOENT) {
544 : : printf("Test failed to detect NULL ring lookup\n");
545 : 0 : goto test_fail;
546 : : }
547 : :
548 : : /* Test to if a non-power of 2 count causes the create
549 : : * function to fail correctly
550 : : */
551 : 5 : rp = test_ring_create("test_ring_count", esize[i], 4097,
552 : : SOCKET_ID_ANY, 0);
553 [ - + ]: 5 : if (rp != NULL)
554 : 0 : goto test_fail;
555 : :
556 : 5 : rp = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
557 : : SOCKET_ID_ANY,
558 : : RING_F_SP_ENQ | RING_F_SC_DEQ);
559 [ - + ]: 5 : if (rp == NULL) {
560 : : printf("test_ring_negative fail to create ring\n");
561 : 0 : goto test_fail;
562 : : }
563 : :
564 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_lookup("test_ring_negative") == rp,
565 : : rp, goto test_fail);
566 : :
567 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto test_fail);
568 : :
569 : : /* Tests if it would always fail to create ring with an used
570 : : * ring name.
571 : : */
572 : 5 : rt = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
573 : : SOCKET_ID_ANY, 0);
574 [ - + ]: 5 : if (rt != NULL)
575 : 0 : goto test_fail;
576 : :
577 : 5 : rte_ring_free(rp);
578 : : rp = NULL;
579 : : }
580 : :
581 : : return 0;
582 : :
583 : 0 : test_fail:
584 : :
585 : 0 : rte_ring_free(rp);
586 : 0 : return -1;
587 : : }
588 : :
589 : : /*
590 : : * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
591 : : * Random number of elements are enqueued and dequeued.
592 : : */
593 : : static int
594 : 14 : test_ring_burst_bulk_tests1(unsigned int test_idx)
595 : : {
596 : : struct rte_ring *r;
597 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
598 : : int ret;
599 : : unsigned int i, j, temp_sz;
600 : : int rand;
601 : : const unsigned int rsz = RING_SIZE - 1;
602 : :
603 [ + + ]: 84 : for (i = 0; i < RTE_DIM(esize); i++) {
604 : 70 : test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
605 : 70 : test_enqdeq_impl[test_idx].api_type, esize[i]);
606 : :
607 : : /* Create the ring */
608 : 70 : r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
609 : : RING_SIZE, SOCKET_ID_ANY,
610 : 70 : test_enqdeq_impl[test_idx].create_flags);
611 : :
612 : : /* alloc dummy object pointers */
613 : 70 : src = test_ring_calloc(RING_SIZE * 2, esize[i]);
614 [ - + ]: 70 : if (src == NULL)
615 : 0 : goto fail;
616 : : test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
617 : : cur_src = src;
618 : :
619 : : /* alloc some room for copied objects */
620 : 70 : dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
621 [ - + ]: 70 : if (dst == NULL)
622 : 0 : goto fail;
623 : : cur_dst = dst;
624 : :
625 : : printf("Random full/empty test\n");
626 : :
627 [ + + ]: 630 : for (j = 0; j != TEST_RING_FULL_EMPTY_ITER; j++) {
628 : : /* random shift in the ring */
629 : 560 : rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
630 : : printf("%s: iteration %u, random shift: %u;\n",
631 : : __func__, i, rand);
632 : 560 : ret = test_ring_enq_impl(r, cur_src, esize[i], rand,
633 : : test_idx);
634 [ - + ]: 560 : TEST_RING_VERIFY(ret != 0, r, goto fail);
635 : :
636 : 560 : ret = test_ring_deq_impl(r, cur_dst, esize[i], rand,
637 : : test_idx);
638 [ - + ]: 560 : TEST_RING_VERIFY(ret == rand, r, goto fail);
639 : :
640 : : /* fill the ring */
641 : 560 : ret = test_ring_enq_impl(r, cur_src, esize[i], rsz,
642 : : test_idx);
643 [ - + ]: 560 : TEST_RING_VERIFY(ret != 0, r, goto fail);
644 : :
645 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_free_count(r) == 0, r, goto fail);
646 [ - + ]: 560 : TEST_RING_VERIFY(rsz == rte_ring_count(r), r, goto fail);
647 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_full(r), r, goto fail);
648 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_empty(r) == 0, r, goto fail);
649 : :
650 : : /* empty the ring */
651 : 560 : ret = test_ring_deq_impl(r, cur_dst, esize[i], rsz,
652 : : test_idx);
653 [ - + ]: 560 : TEST_RING_VERIFY(ret == (int)rsz, r, goto fail);
654 : :
655 [ - + ]: 560 : TEST_RING_VERIFY(rsz == rte_ring_free_count(r), r, goto fail);
656 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_count(r) == 0, r, goto fail);
657 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_full(r) == 0, r, goto fail);
658 [ - + ]: 560 : TEST_RING_VERIFY(rte_ring_empty(r), r, goto fail);
659 : :
660 : : /* check data */
661 : : temp_sz = rsz * sizeof(void *);
662 [ + + ]: 560 : if (esize[i] != -1)
663 : 448 : temp_sz = rsz * esize[i];
664 [ - + ]: 560 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
665 : : temp_sz) == 0, r, goto fail);
666 : : }
667 : :
668 : : /* Free memory before test completed */
669 : 70 : rte_ring_free(r);
670 : 70 : rte_free(src);
671 : 70 : rte_free(dst);
672 : : r = NULL;
673 : : src = NULL;
674 : : dst = NULL;
675 : : }
676 : :
677 : : return 0;
678 : 0 : fail:
679 : 0 : rte_ring_free(r);
680 : 0 : rte_free(src);
681 : 0 : rte_free(dst);
682 : 0 : return -1;
683 : : }
684 : :
685 : : /*
686 : : * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
687 : : * Sequence of simple enqueues/dequeues and validate the enqueued and
688 : : * dequeued data.
689 : : */
690 : : static int
691 : 14 : test_ring_burst_bulk_tests2(unsigned int test_idx)
692 : : {
693 : : struct rte_ring *r;
694 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
695 : : int ret;
696 : : unsigned int i;
697 : :
698 [ + + ]: 84 : for (i = 0; i < RTE_DIM(esize); i++) {
699 : 70 : test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
700 : 70 : test_enqdeq_impl[test_idx].api_type, esize[i]);
701 : :
702 : : /* Create the ring */
703 : 70 : r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
704 : : RING_SIZE, SOCKET_ID_ANY,
705 : 70 : test_enqdeq_impl[test_idx].create_flags);
706 : :
707 : : /* alloc dummy object pointers */
708 : 70 : src = test_ring_calloc(RING_SIZE * 2, esize[i]);
709 [ - + ]: 70 : if (src == NULL)
710 : 0 : goto fail;
711 : : test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
712 : : cur_src = src;
713 : :
714 : : /* alloc some room for copied objects */
715 : 70 : dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
716 [ - + ]: 70 : if (dst == NULL)
717 : 0 : goto fail;
718 : : cur_dst = dst;
719 : :
720 : : printf("enqueue 1 obj\n");
721 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], 1, test_idx);
722 [ - + ]: 70 : TEST_RING_VERIFY(ret == 1, r, goto fail);
723 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
724 : :
725 : : printf("enqueue 2 objs\n");
726 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], 2, test_idx);
727 [ - + ]: 70 : TEST_RING_VERIFY(ret == 2, r, goto fail);
728 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
729 : :
730 : : printf("enqueue MAX_BULK objs\n");
731 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
732 : : test_idx);
733 [ - + ]: 70 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
734 : :
735 : : printf("dequeue 1 obj\n");
736 : 70 : ret = test_ring_deq_impl(r, cur_dst, esize[i], 1, test_idx);
737 [ - + ]: 70 : TEST_RING_VERIFY(ret == 1, r, goto fail);
738 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
739 : :
740 : : printf("dequeue 2 objs\n");
741 : 70 : ret = test_ring_deq_impl(r, cur_dst, esize[i], 2, test_idx);
742 [ - + ]: 70 : TEST_RING_VERIFY(ret == 2, r, goto fail);
743 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
744 : :
745 : : printf("dequeue MAX_BULK objs\n");
746 : 70 : ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
747 : : test_idx);
748 [ - + ]: 70 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
749 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK);
750 : :
751 : : /* check data */
752 [ - + ]: 70 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
753 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
754 : : r, goto fail);
755 : :
756 : : /* Free memory before test completed */
757 : 70 : rte_ring_free(r);
758 : 70 : rte_free(src);
759 : 70 : rte_free(dst);
760 : : r = NULL;
761 : : src = NULL;
762 : : dst = NULL;
763 : : }
764 : :
765 : : return 0;
766 : 0 : fail:
767 : 0 : rte_ring_free(r);
768 : 0 : rte_free(src);
769 : 0 : rte_free(dst);
770 : 0 : return -1;
771 : : }
772 : :
773 : : /*
774 : : * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
775 : : * Enqueue and dequeue to cover the entire ring length.
776 : : */
777 : : static int
778 : 14 : test_ring_burst_bulk_tests3(unsigned int test_idx)
779 : : {
780 : : struct rte_ring *r;
781 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
782 : : int ret;
783 : : unsigned int i, j;
784 : :
785 [ + + ]: 84 : for (i = 0; i < RTE_DIM(esize); i++) {
786 : 70 : test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
787 : 70 : test_enqdeq_impl[test_idx].api_type, esize[i]);
788 : :
789 : : /* Create the ring */
790 : 70 : r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
791 : : RING_SIZE, SOCKET_ID_ANY,
792 : 70 : test_enqdeq_impl[test_idx].create_flags);
793 : :
794 : : /* alloc dummy object pointers */
795 : 70 : src = test_ring_calloc(RING_SIZE * 2, esize[i]);
796 [ - + ]: 70 : if (src == NULL)
797 : 0 : goto fail;
798 : : test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
799 : : cur_src = src;
800 : :
801 : : /* alloc some room for copied objects */
802 : 70 : dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
803 [ - + ]: 70 : if (dst == NULL)
804 : 0 : goto fail;
805 : : cur_dst = dst;
806 : :
807 : : printf("fill and empty the ring\n");
808 [ + + ]: 9030 : for (j = 0; j < RING_SIZE / MAX_BULK; j++) {
809 : 8960 : ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
810 : : test_idx);
811 [ - + ]: 8960 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
812 : : cur_src = test_ring_inc_ptr(cur_src, esize[i],
813 : : MAX_BULK);
814 : :
815 : 8960 : ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
816 : : test_idx);
817 [ - + ]: 8960 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
818 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
819 : : MAX_BULK);
820 : : }
821 : :
822 : : /* check data */
823 [ - + ]: 70 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
824 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
825 : : r, goto fail);
826 : :
827 : : /* Free memory before test completed */
828 : 70 : rte_ring_free(r);
829 : 70 : rte_free(src);
830 : 70 : rte_free(dst);
831 : : r = NULL;
832 : : src = NULL;
833 : : dst = NULL;
834 : : }
835 : :
836 : : return 0;
837 : 0 : fail:
838 : 0 : rte_ring_free(r);
839 : 0 : rte_free(src);
840 : 0 : rte_free(dst);
841 : 0 : return -1;
842 : : }
843 : :
844 : : /*
845 : : * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
846 : : * Enqueue till the ring is full and dequeue till the ring becomes empty.
847 : : */
848 : : static int
849 : 14 : test_ring_burst_bulk_tests4(unsigned int test_idx)
850 : : {
851 : : struct rte_ring *r;
852 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
853 : : int ret;
854 : : unsigned int i, j;
855 : : unsigned int api_type, num_elems;
856 : :
857 : 14 : api_type = test_enqdeq_impl[test_idx].api_type;
858 : :
859 [ + + ]: 84 : for (i = 0; i < RTE_DIM(esize); i++) {
860 : 70 : test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
861 : 70 : test_enqdeq_impl[test_idx].api_type, esize[i]);
862 : :
863 : : /* Create the ring */
864 : 70 : r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
865 : : RING_SIZE, SOCKET_ID_ANY,
866 : 70 : test_enqdeq_impl[test_idx].create_flags);
867 : :
868 : : /* alloc dummy object pointers */
869 : 70 : src = test_ring_calloc(RING_SIZE * 2, esize[i]);
870 [ - + ]: 70 : if (src == NULL)
871 : 0 : goto fail;
872 : : test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
873 : : cur_src = src;
874 : :
875 : : /* alloc some room for copied objects */
876 : 70 : dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
877 [ - + ]: 70 : if (dst == NULL)
878 : 0 : goto fail;
879 : : cur_dst = dst;
880 : :
881 : : printf("Test enqueue without enough memory space\n");
882 [ + + ]: 8960 : for (j = 0; j < (RING_SIZE/MAX_BULK - 1); j++) {
883 : 8890 : ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
884 : : test_idx);
885 [ - + ]: 8890 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
886 : : cur_src = test_ring_inc_ptr(cur_src, esize[i],
887 : : MAX_BULK);
888 : : }
889 : :
890 : : printf("Enqueue 2 objects, free entries = MAX_BULK - 2\n");
891 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], 2, test_idx);
892 [ - + ]: 70 : TEST_RING_VERIFY(ret == 2, r, goto fail);
893 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
894 : :
895 : : printf("Enqueue the remaining entries = MAX_BULK - 3\n");
896 : : /* Bulk APIs enqueue exact number of elements */
897 [ + + ]: 70 : if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
898 : : num_elems = MAX_BULK - 3;
899 : : else
900 : : num_elems = MAX_BULK;
901 : : /* Always one free entry left */
902 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], num_elems,
903 : : test_idx);
904 [ - + ]: 70 : TEST_RING_VERIFY(ret == MAX_BULK - 3, r, goto fail);
905 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK - 3);
906 : :
907 : : printf("Test if ring is full\n");
908 [ - + ]: 70 : TEST_RING_VERIFY(rte_ring_full(r) == 1, r, goto fail);
909 : :
910 : : printf("Test enqueue for a full entry\n");
911 : 70 : ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
912 : : test_idx);
913 [ - + ]: 70 : TEST_RING_VERIFY(ret == 0, r, goto fail);
914 : :
915 : : printf("Test dequeue without enough objects\n");
916 [ + + ]: 8960 : for (j = 0; j < RING_SIZE / MAX_BULK - 1; j++) {
917 : 8890 : ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
918 : : test_idx);
919 [ - + ]: 8890 : TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
920 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
921 : : MAX_BULK);
922 : : }
923 : :
924 : : /* Available memory space for the exact MAX_BULK entries */
925 : 70 : ret = test_ring_deq_impl(r, cur_dst, esize[i], 2, test_idx);
926 [ - + ]: 70 : TEST_RING_VERIFY(ret == 2, r, goto fail);
927 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
928 : :
929 : : /* Bulk APIs enqueue exact number of elements */
930 : : if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
931 : : num_elems = MAX_BULK - 3;
932 : : else
933 : : num_elems = MAX_BULK;
934 : 70 : ret = test_ring_deq_impl(r, cur_dst, esize[i], num_elems,
935 : : test_idx);
936 [ - + ]: 70 : TEST_RING_VERIFY(ret == MAX_BULK - 3, r, goto fail);
937 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK - 3);
938 : :
939 : : printf("Test if ring is empty\n");
940 : : /* Check if ring is empty */
941 [ - + ]: 70 : TEST_RING_VERIFY(rte_ring_empty(r) == 1, r, goto fail);
942 : :
943 : : /* check data */
944 [ - + ]: 70 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
945 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
946 : : r, goto fail);
947 : :
948 : : /* Free memory before test completed */
949 : 70 : rte_ring_free(r);
950 : 70 : rte_free(src);
951 : 70 : rte_free(dst);
952 : : r = NULL;
953 : : src = NULL;
954 : : dst = NULL;
955 : : }
956 : :
957 : : return 0;
958 : 0 : fail:
959 : 0 : rte_ring_free(r);
960 : 0 : rte_free(src);
961 : 0 : rte_free(dst);
962 : 0 : return -1;
963 : : }
964 : :
965 : : /*
966 : : * Test default, single element, bulk and burst APIs
967 : : */
968 : : static int
969 : 1 : test_ring_basic_ex(void)
970 : : {
971 : : int ret = -1;
972 : : unsigned int i, j;
973 : : struct rte_ring *rp = NULL;
974 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
975 : :
976 [ + + ]: 6 : for (i = 0; i < RTE_DIM(esize); i++) {
977 : 5 : rp = test_ring_create("test_ring_basic_ex", esize[i], RING_SIZE,
978 : : SOCKET_ID_ANY,
979 : : RING_F_SP_ENQ | RING_F_SC_DEQ);
980 [ - + ]: 5 : if (rp == NULL) {
981 : : printf("%s: failed to create ring\n", __func__);
982 : 0 : goto fail_test;
983 : : }
984 : :
985 : : /* alloc dummy object pointers */
986 : 5 : src = test_ring_calloc(RING_SIZE, esize[i]);
987 [ - + ]: 5 : if (src == NULL) {
988 : : printf("%s: failed to alloc src memory\n", __func__);
989 : 0 : goto fail_test;
990 : : }
991 : : test_ring_mem_init(src, RING_SIZE, esize[i]);
992 : : cur_src = src;
993 : :
994 : : /* alloc some room for copied objects */
995 : 5 : dst = test_ring_calloc(RING_SIZE, esize[i]);
996 [ - + ]: 5 : if (dst == NULL) {
997 : : printf("%s: failed to alloc dst memory\n", __func__);
998 : 0 : goto fail_test;
999 : : }
1000 : : cur_dst = dst;
1001 : :
1002 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_lookup("test_ring_basic_ex") == rp,
1003 : : rp, goto fail_test);
1004 : :
1005 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto fail_test);
1006 : :
1007 : : printf("%u ring entries are now free\n",
1008 : : rte_ring_free_count(rp));
1009 : :
1010 [ + + ]: 20480 : for (j = 0; j < RING_SIZE - 1; j++) {
1011 : 20475 : ret = test_ring_enqueue(rp, cur_src, esize[i], 1,
1012 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1013 [ - + ]: 20475 : TEST_RING_VERIFY(ret == 0, rp, goto fail_test);
1014 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
1015 : : }
1016 : :
1017 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_full(rp) == 1, rp, goto fail_test);
1018 : :
1019 [ + + ]: 20480 : for (j = 0; j < RING_SIZE - 1; j++) {
1020 : 20475 : ret = test_ring_dequeue(rp, cur_dst, esize[i], 1,
1021 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1022 [ - + ]: 20475 : TEST_RING_VERIFY(ret == 0, rp, goto fail_test);
1023 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
1024 : : }
1025 : :
1026 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto fail_test);
1027 : :
1028 : : /* check data */
1029 [ - + ]: 5 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1030 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
1031 : : rp, goto fail_test);
1032 : :
1033 : : /* Following tests use the configured flags to decide
1034 : : * SP/SC or MP/MC.
1035 : : */
1036 : : /* reset memory of dst */
1037 : : memset(dst, 0, RTE_PTR_DIFF(cur_dst, dst));
1038 : :
1039 : : /* reset cur_src and cur_dst */
1040 : : cur_src = src;
1041 : : cur_dst = dst;
1042 : :
1043 : : /* Covering the ring burst operation */
1044 : 5 : ret = test_ring_enqueue(rp, cur_src, esize[i], 2,
1045 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1046 [ - + ]: 5 : TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1047 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
1048 : :
1049 : 5 : ret = test_ring_dequeue(rp, cur_dst, esize[i], 2,
1050 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1051 [ - + ]: 5 : TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1052 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
1053 : :
1054 : : /* Covering the ring bulk operation */
1055 : 5 : ret = test_ring_enqueue(rp, cur_src, esize[i], 2,
1056 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
1057 [ - + ]: 5 : TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1058 : :
1059 : 5 : ret = test_ring_dequeue(rp, cur_dst, esize[i], 2,
1060 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
1061 [ - + ]: 5 : TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1062 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
1063 : :
1064 : : /* check data */
1065 [ - + ]: 5 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1066 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
1067 : : rp, goto fail_test);
1068 : :
1069 : 5 : rte_ring_free(rp);
1070 : 5 : rte_free(src);
1071 : 5 : rte_free(dst);
1072 : : rp = NULL;
1073 : : src = NULL;
1074 : : dst = NULL;
1075 : : }
1076 : :
1077 : : return 0;
1078 : :
1079 : 0 : fail_test:
1080 : 0 : rte_ring_free(rp);
1081 : 0 : rte_free(src);
1082 : 0 : rte_free(dst);
1083 : 0 : return -1;
1084 : : }
1085 : :
1086 : : /*
1087 : : * Basic test cases with exact size ring.
1088 : : */
1089 : : static int
1090 : 1 : test_ring_with_exact_size(void)
1091 : : {
1092 : : struct rte_ring *std_r = NULL, *exact_sz_r = NULL;
1093 : : void **src_orig = NULL, **dst_orig = NULL;
1094 : : void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
1095 : : const unsigned int ring_sz = 16;
1096 : : unsigned int i, j;
1097 : : int ret = -1;
1098 : :
1099 [ + + ]: 6 : for (i = 0; i < RTE_DIM(esize); i++) {
1100 : 5 : test_ring_print_test_string("Test exact size ring",
1101 : : TEST_RING_IGNORE_API_TYPE,
1102 : 5 : esize[i]);
1103 : :
1104 : 5 : std_r = test_ring_create("std", esize[i], ring_sz,
1105 : 5 : rte_socket_id(),
1106 : : RING_F_SP_ENQ | RING_F_SC_DEQ);
1107 [ - + ]: 5 : if (std_r == NULL) {
1108 : : printf("%s: error, can't create std ring\n", __func__);
1109 : 0 : goto test_fail;
1110 : : }
1111 : 5 : exact_sz_r = test_ring_create("exact sz", esize[i], ring_sz,
1112 : 5 : rte_socket_id(),
1113 : : RING_F_SP_ENQ | RING_F_SC_DEQ |
1114 : : RING_F_EXACT_SZ);
1115 [ - + ]: 5 : if (exact_sz_r == NULL) {
1116 : : printf("%s: error, can't create exact size ring\n",
1117 : : __func__);
1118 : 0 : goto test_fail;
1119 : : }
1120 : :
1121 : : /* alloc object pointers. Allocate one extra object
1122 : : * and create an unaligned address.
1123 : : */
1124 : 5 : src_orig = test_ring_calloc(17, esize[i]);
1125 [ - + ]: 5 : if (src_orig == NULL)
1126 : 0 : goto test_fail;
1127 : : test_ring_mem_init(src_orig, 17, esize[i]);
1128 : 5 : src = (void **)((uintptr_t)src_orig + 1);
1129 : : cur_src = src;
1130 : :
1131 : 5 : dst_orig = test_ring_calloc(17, esize[i]);
1132 [ - + ]: 5 : if (dst_orig == NULL)
1133 : 0 : goto test_fail;
1134 [ + - ]: 5 : dst = (void **)((uintptr_t)dst_orig + 1);
1135 : : cur_dst = dst;
1136 : :
1137 : : /*
1138 : : * Check that the exact size ring is bigger than the
1139 : : * standard ring
1140 : : */
1141 [ + - ]: 5 : TEST_RING_VERIFY(rte_ring_get_size(std_r) <=
1142 : : rte_ring_get_size(exact_sz_r),
1143 : : std_r, goto test_fail);
1144 : :
1145 : : /*
1146 : : * check that the exact_sz_ring can hold one more element
1147 : : * than the standard ring. (16 vs 15 elements)
1148 : : */
1149 [ + + ]: 80 : for (j = 0; j < ring_sz - 1; j++) {
1150 : 75 : ret = test_ring_enqueue(std_r, cur_src, esize[i], 1,
1151 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1152 [ - + ]: 75 : TEST_RING_VERIFY(ret == 0, std_r, goto test_fail);
1153 : 75 : ret = test_ring_enqueue(exact_sz_r, cur_src, esize[i], 1,
1154 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1155 [ - + ]: 75 : TEST_RING_VERIFY(ret == 0, exact_sz_r, goto test_fail);
1156 : : cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
1157 : : }
1158 : 5 : ret = test_ring_enqueue(std_r, cur_src, esize[i], 1,
1159 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1160 [ - + ]: 5 : TEST_RING_VERIFY(ret == -ENOBUFS, std_r, goto test_fail);
1161 : 5 : ret = test_ring_enqueue(exact_sz_r, cur_src, esize[i], 1,
1162 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1163 [ - + ]: 5 : TEST_RING_VERIFY(ret != -ENOBUFS, exact_sz_r, goto test_fail);
1164 : :
1165 : : /* check that dequeue returns the expected number of elements */
1166 : 5 : ret = test_ring_dequeue(exact_sz_r, cur_dst, esize[i], ring_sz,
1167 : : TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1168 [ - + ]: 5 : TEST_RING_VERIFY(ret == (int)ring_sz, exact_sz_r, goto test_fail);
1169 : : cur_dst = test_ring_inc_ptr(cur_dst, esize[i], ring_sz);
1170 : :
1171 : : /* check that the capacity function returns expected value */
1172 [ - + ]: 5 : TEST_RING_VERIFY(rte_ring_get_capacity(exact_sz_r) == ring_sz,
1173 : : exact_sz_r, goto test_fail);
1174 : :
1175 : : /* check data */
1176 [ - + ]: 5 : TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1177 : : RTE_PTR_DIFF(cur_dst, dst)) == 0,
1178 : : exact_sz_r, goto test_fail);
1179 : :
1180 : 5 : rte_free(src_orig);
1181 : 5 : rte_free(dst_orig);
1182 : 5 : rte_ring_free(std_r);
1183 : 5 : rte_ring_free(exact_sz_r);
1184 : : src_orig = NULL;
1185 : : dst_orig = NULL;
1186 : : std_r = NULL;
1187 : : exact_sz_r = NULL;
1188 : : }
1189 : :
1190 : : return 0;
1191 : :
1192 : 0 : test_fail:
1193 : 0 : rte_free(src_orig);
1194 : 0 : rte_free(dst_orig);
1195 : 0 : rte_ring_free(std_r);
1196 : 0 : rte_ring_free(exact_sz_r);
1197 : 0 : return -1;
1198 : : }
1199 : :
1200 : : static int
1201 : 1 : test_ring(void)
1202 : : {
1203 : : int32_t rc;
1204 : : unsigned int i;
1205 : :
1206 : : /* Negative test cases */
1207 [ - + ]: 1 : if (test_ring_negative_tests() < 0)
1208 : 0 : goto test_fail;
1209 : :
1210 : : /* Some basic operations */
1211 [ - + ]: 1 : if (test_ring_basic_ex() < 0)
1212 : 0 : goto test_fail;
1213 : :
1214 [ + - ]: 1 : if (test_ring_with_exact_size() < 0)
1215 : 0 : goto test_fail;
1216 : :
1217 : : /* Burst and bulk operations with sp/sc, mp/mc and default.
1218 : : * The test cases are split into smaller test cases to
1219 : : * help clang compile faster.
1220 : : */
1221 [ + + ]: 15 : for (i = 0; i != RTE_DIM(test_enqdeq_impl); i++) {
1222 : :
1223 : :
1224 : 14 : rc = test_ring_burst_bulk_tests1(i);
1225 [ - + ]: 14 : if (rc < 0)
1226 : 0 : goto test_fail;
1227 : :
1228 : 14 : rc = test_ring_burst_bulk_tests2(i);
1229 [ - + ]: 14 : if (rc < 0)
1230 : 0 : goto test_fail;
1231 : :
1232 : 14 : rc = test_ring_burst_bulk_tests3(i);
1233 [ - + ]: 14 : if (rc < 0)
1234 : 0 : goto test_fail;
1235 : :
1236 : 14 : rc = test_ring_burst_bulk_tests4(i);
1237 [ - + ]: 14 : if (rc < 0)
1238 : 0 : goto test_fail;
1239 : : }
1240 : :
1241 : : /* dump the ring status */
1242 : 1 : rte_ring_list_dump(stdout);
1243 : :
1244 : 1 : return 0;
1245 : :
1246 : : test_fail:
1247 : :
1248 : : return -1;
1249 : : }
1250 : :
1251 : 254 : REGISTER_FAST_TEST(ring_autotest, true, true, test_ring);
|