xref: /dpdk/app/test/test_ring.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
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 }
243