test/service: fix race condition on stopping lcore
[dpdk.git] / app / test / test_ring.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Arm Limited
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_ring.h>
7 #include <rte_ring_elem.h>
8
9 /* API type to call
10  * rte_ring_<sp/mp or sc/mc>_enqueue_<bulk/burst>
11  * TEST_RING_THREAD_DEF - Uses configured SPSC/MPMC calls
12  * TEST_RING_THREAD_SPSC - Calls SP or SC API
13  * TEST_RING_THREAD_MPMC - Calls MP or MC API
14  */
15 #define TEST_RING_THREAD_DEF 1
16 #define TEST_RING_THREAD_SPSC 2
17 #define TEST_RING_THREAD_MPMC 4
18
19 /* API type to call
20  * TEST_RING_ELEM_SINGLE - Calls single element APIs
21  * TEST_RING_ELEM_BULK - Calls bulk APIs
22  * TEST_RING_ELEM_BURST - Calls burst APIs
23  */
24 #define TEST_RING_ELEM_SINGLE 8
25 #define TEST_RING_ELEM_BULK 16
26 #define TEST_RING_ELEM_BURST 32
27
28 #define TEST_RING_IGNORE_API_TYPE ~0U
29
30 /* This function is placed here as it is required for both
31  * performance and functional tests.
32  */
33 static inline struct rte_ring*
34 test_ring_create(const char *name, int esize, unsigned int count,
35                 int socket_id, unsigned int flags)
36 {
37         /* Legacy queue APIs? */
38         if ((esize) == -1)
39                 return rte_ring_create((name), (count), (socket_id), (flags));
40         else
41                 return rte_ring_create_elem((name), (esize), (count),
42                                                 (socket_id), (flags));
43 }
44
45 static __rte_always_inline unsigned int
46 test_ring_enqueue(struct rte_ring *r, void **obj, int esize, unsigned int n,
47                         unsigned int api_type)
48 {
49         /* Legacy queue APIs? */
50         if ((esize) == -1)
51                 switch (api_type) {
52                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
53                         return rte_ring_enqueue(r, obj);
54                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
55                         return rte_ring_sp_enqueue(r, obj);
56                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
57                         return rte_ring_mp_enqueue(r, obj);
58                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
59                         return rte_ring_enqueue_bulk(r, obj, n, NULL);
60                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
61                         return rte_ring_sp_enqueue_bulk(r, obj, n, NULL);
62                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
63                         return rte_ring_mp_enqueue_bulk(r, obj, n, NULL);
64                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
65                         return rte_ring_enqueue_burst(r, obj, n, NULL);
66                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
67                         return rte_ring_sp_enqueue_burst(r, obj, n, NULL);
68                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
69                         return rte_ring_mp_enqueue_burst(r, obj, n, NULL);
70                 default:
71                         printf("Invalid API type\n");
72                         return 0;
73                 }
74         else
75                 switch (api_type) {
76                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
77                         return rte_ring_enqueue_elem(r, obj, esize);
78                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
79                         return rte_ring_sp_enqueue_elem(r, obj, esize);
80                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
81                         return rte_ring_mp_enqueue_elem(r, obj, esize);
82                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
83                         return rte_ring_enqueue_bulk_elem(r, obj, esize, n,
84                                                                 NULL);
85                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
86                         return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, n,
87                                                                 NULL);
88                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
89                         return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, n,
90                                                                 NULL);
91                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
92                         return rte_ring_enqueue_burst_elem(r, obj, esize, n,
93                                                                 NULL);
94                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
95                         return rte_ring_sp_enqueue_burst_elem(r, obj, esize, n,
96                                                                 NULL);
97                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
98                         return rte_ring_mp_enqueue_burst_elem(r, obj, esize, n,
99                                                                 NULL);
100                 default:
101                         printf("Invalid API type\n");
102                         return 0;
103                 }
104 }
105
106 static __rte_always_inline unsigned int
107 test_ring_dequeue(struct rte_ring *r, void **obj, int esize, unsigned int n,
108                         unsigned int api_type)
109 {
110         /* Legacy queue APIs? */
111         if ((esize) == -1)
112                 switch (api_type) {
113                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
114                         return rte_ring_dequeue(r, obj);
115                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
116                         return rte_ring_sc_dequeue(r, obj);
117                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
118                         return rte_ring_mc_dequeue(r, obj);
119                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
120                         return rte_ring_dequeue_bulk(r, obj, n, NULL);
121                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
122                         return rte_ring_sc_dequeue_bulk(r, obj, n, NULL);
123                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
124                         return rte_ring_mc_dequeue_bulk(r, obj, n, NULL);
125                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
126                         return rte_ring_dequeue_burst(r, obj, n, NULL);
127                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
128                         return rte_ring_sc_dequeue_burst(r, obj, n, NULL);
129                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
130                         return rte_ring_mc_dequeue_burst(r, obj, n, NULL);
131                 default:
132                         printf("Invalid API type\n");
133                         return 0;
134                 }
135         else
136                 switch (api_type) {
137                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
138                         return rte_ring_dequeue_elem(r, obj, esize);
139                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
140                         return rte_ring_sc_dequeue_elem(r, obj, esize);
141                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
142                         return rte_ring_mc_dequeue_elem(r, obj, esize);
143                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
144                         return rte_ring_dequeue_bulk_elem(r, obj, esize,
145                                                                 n, NULL);
146                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
147                         return rte_ring_sc_dequeue_bulk_elem(r, obj, esize,
148                                                                 n, NULL);
149                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
150                         return rte_ring_mc_dequeue_bulk_elem(r, obj, esize,
151                                                                 n, NULL);
152                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
153                         return rte_ring_dequeue_burst_elem(r, obj, esize,
154                                                                 n, NULL);
155                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
156                         return rte_ring_sc_dequeue_burst_elem(r, obj, esize,
157                                                                 n, NULL);
158                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
159                         return rte_ring_mc_dequeue_burst_elem(r, obj, esize,
160                                                                 n, NULL);
161                 default:
162                         printf("Invalid API type\n");
163                         return 0;
164                 }
165 }
166
167 /* This function is placed here as it is required for both
168  * performance and functional tests.
169  */
170 static __rte_always_inline void *
171 test_ring_calloc(unsigned int rsize, int esize)
172 {
173         unsigned int sz;
174         void *p;
175
176         /* Legacy queue APIs? */
177         if (esize == -1)
178                 sz = sizeof(void *);
179         else
180                 sz = esize;
181
182         p = rte_zmalloc(NULL, rsize * sz, RTE_CACHE_LINE_SIZE);
183         if (p == NULL)
184                 printf("Failed to allocate memory\n");
185
186         return p;
187 }