bpf: allow self-xor operation
[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 inline void*
46 test_ring_inc_ptr(void *obj, int esize, unsigned int n)
47 {
48         size_t sz;
49
50         sz = sizeof(void *);
51         /* Legacy queue APIs? */
52         if (esize != -1)
53                 sz = esize;
54
55         return (void *)((uint32_t *)obj + (n * sz / sizeof(uint32_t)));
56 }
57
58 static inline void
59 test_ring_mem_copy(void *dst, void * const *src, int esize, unsigned int num)
60 {
61         size_t sz;
62
63         sz = num * sizeof(void *);
64         if (esize != -1)
65                 sz = esize * num;
66
67         memcpy(dst, src, sz);
68 }
69
70 /* Copy to the ring memory */
71 static inline void
72 test_ring_copy_to(struct rte_ring_zc_data *zcd, void * const *src, int esize,
73         unsigned int num)
74 {
75         test_ring_mem_copy(zcd->ptr1, src, esize, zcd->n1);
76         if (zcd->n1 != num) {
77                 if (esize == -1)
78                         src = src + zcd->n1;
79                 else
80                         src = (void * const *)((const uint32_t *)src +
81                                         (zcd->n1 * esize / sizeof(uint32_t)));
82                 test_ring_mem_copy(zcd->ptr2, src,
83                                         esize, num - zcd->n1);
84         }
85 }
86
87 /* Copy from the ring memory */
88 static inline void
89 test_ring_copy_from(struct rte_ring_zc_data *zcd, void *dst, int esize,
90         unsigned int num)
91 {
92         test_ring_mem_copy(dst, zcd->ptr1, esize, zcd->n1);
93
94         if (zcd->n1 != num) {
95                 dst = test_ring_inc_ptr(dst, esize, zcd->n1);
96                 test_ring_mem_copy(dst, zcd->ptr2, esize, num - zcd->n1);
97         }
98 }
99
100 static __rte_always_inline unsigned int
101 test_ring_enqueue(struct rte_ring *r, void **obj, int esize, unsigned int n,
102                         unsigned int api_type)
103 {
104         /* Legacy queue APIs? */
105         if (esize == -1)
106                 switch (api_type) {
107                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
108                         return rte_ring_enqueue(r, *obj);
109                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
110                         return rte_ring_sp_enqueue(r, *obj);
111                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
112                         return rte_ring_mp_enqueue(r, *obj);
113                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
114                         return rte_ring_enqueue_bulk(r, obj, n, NULL);
115                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
116                         return rte_ring_sp_enqueue_bulk(r, obj, n, NULL);
117                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
118                         return rte_ring_mp_enqueue_bulk(r, obj, n, NULL);
119                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
120                         return rte_ring_enqueue_burst(r, obj, n, NULL);
121                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
122                         return rte_ring_sp_enqueue_burst(r, obj, n, NULL);
123                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
124                         return rte_ring_mp_enqueue_burst(r, obj, n, NULL);
125                 default:
126                         printf("Invalid API type\n");
127                         return 0;
128                 }
129         else
130                 switch (api_type) {
131                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
132                         return rte_ring_enqueue_elem(r, obj, esize);
133                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
134                         return rte_ring_sp_enqueue_elem(r, obj, esize);
135                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
136                         return rte_ring_mp_enqueue_elem(r, obj, esize);
137                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
138                         return rte_ring_enqueue_bulk_elem(r, obj, esize, n,
139                                                                 NULL);
140                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
141                         return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, n,
142                                                                 NULL);
143                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
144                         return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, n,
145                                                                 NULL);
146                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
147                         return rte_ring_enqueue_burst_elem(r, obj, esize, n,
148                                                                 NULL);
149                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
150                         return rte_ring_sp_enqueue_burst_elem(r, obj, esize, n,
151                                                                 NULL);
152                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
153                         return rte_ring_mp_enqueue_burst_elem(r, obj, esize, n,
154                                                                 NULL);
155                 default:
156                         printf("Invalid API type\n");
157                         return 0;
158                 }
159 }
160
161 static __rte_always_inline unsigned int
162 test_ring_dequeue(struct rte_ring *r, void **obj, int esize, unsigned int n,
163                         unsigned int api_type)
164 {
165         /* Legacy queue APIs? */
166         if (esize == -1)
167                 switch (api_type) {
168                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
169                         return rte_ring_dequeue(r, obj);
170                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
171                         return rte_ring_sc_dequeue(r, obj);
172                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
173                         return rte_ring_mc_dequeue(r, obj);
174                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
175                         return rte_ring_dequeue_bulk(r, obj, n, NULL);
176                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
177                         return rte_ring_sc_dequeue_bulk(r, obj, n, NULL);
178                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
179                         return rte_ring_mc_dequeue_bulk(r, obj, n, NULL);
180                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
181                         return rte_ring_dequeue_burst(r, obj, n, NULL);
182                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
183                         return rte_ring_sc_dequeue_burst(r, obj, n, NULL);
184                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
185                         return rte_ring_mc_dequeue_burst(r, obj, n, NULL);
186                 default:
187                         printf("Invalid API type\n");
188                         return 0;
189                 }
190         else
191                 switch (api_type) {
192                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE):
193                         return rte_ring_dequeue_elem(r, obj, esize);
194                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE):
195                         return rte_ring_sc_dequeue_elem(r, obj, esize);
196                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE):
197                         return rte_ring_mc_dequeue_elem(r, obj, esize);
198                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK):
199                         return rte_ring_dequeue_bulk_elem(r, obj, esize,
200                                                                 n, NULL);
201                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK):
202                         return rte_ring_sc_dequeue_bulk_elem(r, obj, esize,
203                                                                 n, NULL);
204                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK):
205                         return rte_ring_mc_dequeue_bulk_elem(r, obj, esize,
206                                                                 n, NULL);
207                 case (TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST):
208                         return rte_ring_dequeue_burst_elem(r, obj, esize,
209                                                                 n, NULL);
210                 case (TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST):
211                         return rte_ring_sc_dequeue_burst_elem(r, obj, esize,
212                                                                 n, NULL);
213                 case (TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST):
214                         return rte_ring_mc_dequeue_burst_elem(r, obj, esize,
215                                                                 n, NULL);
216                 default:
217                         printf("Invalid API type\n");
218                         return 0;
219                 }
220 }
221
222 /* This function is placed here as it is required for both
223  * performance and functional tests.
224  */
225 static __rte_always_inline void *
226 test_ring_calloc(unsigned int rsize, int esize)
227 {
228         unsigned int sz;
229         void *p;
230
231         /* Legacy queue APIs? */
232         if (esize == -1)
233                 sz = sizeof(void *);
234         else
235                 sz = esize;
236
237         p = rte_zmalloc(NULL, rsize * sz, RTE_CACHE_LINE_SIZE);
238         if (p == NULL)
239                 printf("Failed to allocate memory\n");
240
241         return p;
242 }