Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016-2017 Intel Corporation
3 : : * Copyright(c) 2019 Arm Limited
4 : : */
5 : :
6 : : /**
7 : : * @file
8 : : * RTE Event Ring
9 : : *
10 : : * This provides a ring implementation for passing rte_event structures
11 : : * from one core to another.
12 : : */
13 : :
14 : : #ifndef _RTE_EVENT_RING_
15 : : #define _RTE_EVENT_RING_
16 : :
17 : : #include <stdint.h>
18 : :
19 : : #include <rte_common.h>
20 : : #include <rte_ring.h>
21 : : #include <rte_ring_elem.h>
22 : : #include "rte_eventdev.h"
23 : :
24 : : #ifdef __cplusplus
25 : : extern "C" {
26 : : #endif
27 : :
28 : : #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING"
29 : :
30 : : /**
31 : : * Generic ring structure for passing rte_event objects from core to core.
32 : : *
33 : : * Based on the primitives given in the rte_ring library. Designed to be
34 : : * used inside software eventdev implementations and by applications
35 : : * directly as needed.
36 : : */
37 : : struct rte_event_ring {
38 : : struct rte_ring r;
39 : : };
40 : :
41 : : /**
42 : : * Returns the number of events in the ring
43 : : *
44 : : * @param r
45 : : * pointer to the event ring
46 : : * @return
47 : : * the number of events in the ring
48 : : */
49 : : static __rte_always_inline unsigned int
50 : : rte_event_ring_count(const struct rte_event_ring *r)
51 : : {
52 : : return rte_ring_count(&r->r);
53 : : }
54 : :
55 : : /**
56 : : * Returns the amount of free space in the ring
57 : : *
58 : : * @param r
59 : : * pointer to the event ring
60 : : * @return
61 : : * the number of free slots in the ring, i.e. the number of events that
62 : : * can be successfully enqueued before dequeue must be called
63 : : */
64 : : static __rte_always_inline unsigned int
65 : : rte_event_ring_free_count(const struct rte_event_ring *r)
66 : : {
67 : : return rte_ring_free_count(&r->r);
68 : : }
69 : :
70 : :
71 : : /**
72 : : * Enqueue several objects on a ring.
73 : : *
74 : : * This function calls the multi-producer or the single-producer
75 : : * version depending on the default behavior that was specified at
76 : : * ring creation time (see flags).
77 : : *
78 : : * @param r
79 : : * pointer to the event ring
80 : : * @param events
81 : : * pointer to an array of struct rte_event objects
82 : : * @param n
83 : : * The number of events in the array to enqueue
84 : : * @param free_space
85 : : * if non-NULL, returns the amount of space in the ring after the
86 : : * enqueue operation has completed
87 : : * @return
88 : : * the number of objects enqueued, either 0 or n
89 : : */
90 : : static __rte_always_inline unsigned int
91 : : rte_event_ring_enqueue_bulk(struct rte_event_ring *r,
92 : : const struct rte_event *events,
93 : : unsigned int n, uint16_t *free_space)
94 : : {
95 : : unsigned int num;
96 : : uint32_t space;
97 : :
98 : : num = rte_ring_enqueue_bulk_elem(&r->r, events,
99 : : sizeof(struct rte_event), n,
100 : : &space);
101 : :
102 : : if (free_space != NULL)
103 : : *free_space = space;
104 : :
105 : : return num;
106 : : }
107 : :
108 : : /**
109 : : * Dequeue a set of events from a ring
110 : : *
111 : : * Note: this API does not work with pointers to events, rather it copies
112 : : * the events themselves to the destination ``events`` buffer.
113 : : *
114 : : * @param r
115 : : * pointer to the event ring
116 : : * @param events
117 : : * pointer to an array to hold the struct rte_event objects
118 : : * @param n
119 : : * number of events that can be held in the ``events`` array
120 : : * @param available
121 : : * if non-null, is updated to indicate the number of events remaining in
122 : : * the ring once the dequeue has completed
123 : : * @return
124 : : * the number of objects dequeued, either 0 or n
125 : : */
126 : : static __rte_always_inline unsigned int
127 : : rte_event_ring_dequeue_bulk(struct rte_event_ring *r,
128 : : struct rte_event *events,
129 : : unsigned int n, uint16_t *available)
130 : : {
131 : : unsigned int num;
132 : : uint32_t remaining;
133 : :
134 : : num = rte_ring_dequeue_bulk_elem(&r->r, events,
135 : : sizeof(struct rte_event), n,
136 : : &remaining);
137 : :
138 : : if (available != NULL)
139 : : *available = remaining;
140 : :
141 : : return num;
142 : : }
143 : :
144 : : /**
145 : : * Enqueue a set of events onto a ring
146 : : *
147 : : * Note: this API enqueues by copying the events themselves onto the ring,
148 : : * rather than just placing a pointer to each event onto the ring. This
149 : : * means that statically-allocated events can safely be enqueued by this
150 : : * API.
151 : : *
152 : : * @param r
153 : : * pointer to the event ring
154 : : * @param events
155 : : * pointer to an array of struct rte_event objects
156 : : * @param n
157 : : * number of events in the array to enqueue
158 : : * @param free_space
159 : : * if non-null, is updated to indicate the amount of free space in the
160 : : * ring once the enqueue has completed.
161 : : * @return
162 : : * the number of elements, n', enqueued to the ring, 0 <= n' <= n
163 : : */
164 : : static __rte_always_inline unsigned int
165 : : rte_event_ring_enqueue_burst(struct rte_event_ring *r,
166 : : const struct rte_event *events,
167 : : unsigned int n, uint16_t *free_space)
168 : : {
169 : : unsigned int num;
170 : : uint32_t space;
171 : :
172 : : num = rte_ring_enqueue_burst_elem(&r->r, events,
173 : : sizeof(struct rte_event), n,
174 : : &space);
175 : :
176 : : if (free_space != NULL)
177 [ + - ]: 9296 : *free_space = space;
178 : :
179 : : return num;
180 : : }
181 : :
182 : : /**
183 : : * Dequeue a set of events from a ring
184 : : *
185 : : * Note: this API does not work with pointers to events, rather it copies
186 : : * the events themselves to the destination ``events`` buffer.
187 : : *
188 : : * @param r
189 : : * pointer to the event ring
190 : : * @param events
191 : : * pointer to an array to hold the struct rte_event objects
192 : : * @param n
193 : : * number of events that can be held in the ``events`` array
194 : : * @param available
195 : : * if non-null, is updated to indicate the number of events remaining in
196 : : * the ring once the dequeue has completed
197 : : * @return
198 : : * the number of elements, n', dequeued from the ring, 0 <= n' <= n
199 : : */
200 : : static __rte_always_inline unsigned int
201 : : rte_event_ring_dequeue_burst(struct rte_event_ring *r,
202 : : struct rte_event *events,
203 : : unsigned int n, uint16_t *available)
204 : : {
205 : : unsigned int num;
206 : : uint32_t remaining;
207 : :
208 : : num = rte_ring_dequeue_burst_elem(&r->r, events,
209 : : sizeof(struct rte_event), n,
210 : : &remaining);
211 : :
212 : : if (available != NULL)
213 [ + - ]: 1 : *available = remaining;
214 : :
215 : : return num;
216 : : }
217 : :
218 : : /*
219 : : * Initializes an already-allocated ring structure
220 : : *
221 : : * @param r
222 : : * pointer to the ring memory to be initialized
223 : : * @param name
224 : : * name to be given to the ring
225 : : * @param count
226 : : * the number of elements to be stored in the ring. If the flag
227 : : * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
228 : : * usable space in the ring will be ``count - 1`` entries. If the flag
229 : : * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
230 : : * limit - 1, and the usable space will be exactly that requested.
231 : : * @param flags
232 : : * An OR of the following:
233 : : * - RING_F_SP_ENQ: If this flag is set, the default behavior when
234 : : * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
235 : : * is "single-producer". Otherwise, it is "multi-producers".
236 : : * - RING_F_SC_DEQ: If this flag is set, the default behavior when
237 : : * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
238 : : * is "single-consumer". Otherwise, it is "multi-consumers".
239 : : * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
240 : : * be taken as the exact usable size of the ring, and as such does not
241 : : * need to be a power of 2. The underlying ring memory should be a
242 : : * power-of-2 size greater than the count value.
243 : : * @return
244 : : * 0 on success, or a negative value on error.
245 : : */
246 : : int
247 : : rte_event_ring_init(struct rte_event_ring *r, const char *name,
248 : : unsigned int count, unsigned int flags);
249 : :
250 : : /*
251 : : * Create an event ring structure
252 : : *
253 : : * This function allocates memory and initializes an event ring inside that
254 : : * memory.
255 : : *
256 : : * @param name
257 : : * name to be given to the ring
258 : : * @param count
259 : : * the number of elements to be stored in the ring. If the flag
260 : : * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
261 : : * usable space in the ring will be ``count - 1`` entries. If the flag
262 : : * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
263 : : * limit - 1, and the usable space will be exactly that requested.
264 : : * @param socket_id
265 : : * The *socket_id* argument is the socket identifier in case of
266 : : * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
267 : : * constraint for the reserved zone.
268 : : * @param flags
269 : : * An OR of the following:
270 : : * - RING_F_SP_ENQ: If this flag is set, the default behavior when
271 : : * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
272 : : * is "single-producer". Otherwise, it is "multi-producers".
273 : : * - RING_F_SC_DEQ: If this flag is set, the default behavior when
274 : : * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
275 : : * is "single-consumer". Otherwise, it is "multi-consumers".
276 : : * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
277 : : * be taken as the exact usable size of the ring, and as such does not
278 : : * need to be a power of 2. The underlying ring memory should be a
279 : : * power-of-2 size greater than the count value.
280 : : * @return
281 : : * On success, the pointer to the new allocated ring. NULL on error with
282 : : * rte_errno set appropriately. Possible errno values include:
283 : : * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
284 : : * - E_RTE_SECONDARY - function was called from a secondary process instance
285 : : * - EINVAL - count provided is not a power of 2
286 : : * - ENOSPC - the maximum number of memzones has already been allocated
287 : : * - EEXIST - a memzone with the same name already exists
288 : : * - ENOMEM - no appropriate memory area found in which to create memzone
289 : : */
290 : : struct rte_event_ring *
291 : : rte_event_ring_create(const char *name, unsigned int count, int socket_id,
292 : : unsigned int flags);
293 : :
294 : : /**
295 : : * Search for an event ring based on its name
296 : : *
297 : : * @param name
298 : : * The name of the ring.
299 : : * @return
300 : : * The pointer to the ring matching the name, or NULL if not found,
301 : : * with rte_errno set appropriately. Possible rte_errno values include:
302 : : * - ENOENT - required entry not available to return.
303 : : */
304 : : struct rte_event_ring *
305 : : rte_event_ring_lookup(const char *name);
306 : :
307 : : /**
308 : : * De-allocate all memory used by the ring.
309 : : *
310 : : * @param r
311 : : * Pointer to ring to created with rte_event_ring_create().
312 : : * If r is NULL, no operation is performed.
313 : : */
314 : : void
315 : : rte_event_ring_free(struct rte_event_ring *r);
316 : :
317 : : /**
318 : : * Return the size of the event ring.
319 : : *
320 : : * @param r
321 : : * A pointer to the ring structure.
322 : : * @return
323 : : * The size of the data store used by the ring.
324 : : * NOTE: this is not the same as the usable space in the ring. To query that
325 : : * use ``rte_ring_get_capacity()``.
326 : : */
327 : : static inline unsigned int
328 : : rte_event_ring_get_size(const struct rte_event_ring *r)
329 : : {
330 : : return rte_ring_get_size(&r->r);
331 : : }
332 : :
333 : : /**
334 : : * Return the number of elements which can be stored in the event ring.
335 : : *
336 : : * @param r
337 : : * A pointer to the ring structure.
338 : : * @return
339 : : * The usable size of the ring.
340 : : */
341 : : static inline unsigned int
342 : : rte_event_ring_get_capacity(const struct rte_event_ring *r)
343 : : {
344 : : return rte_ring_get_capacity(&r->r);
345 : : }
346 : :
347 : : #ifdef __cplusplus
348 : : }
349 : : #endif
350 : :
351 : : #endif
|