net/mlx5: reorganize flow structures
[dpdk.git] / lib / librte_eventdev / rte_event_ring.h
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_memory.h>
21 #include <rte_malloc.h>
22 #include <rte_ring.h>
23 #include <rte_ring_elem.h>
24 #include "rte_eventdev.h"
25
26 #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING"
27
28 /**
29  * Generic ring structure for passing rte_event objects from core to core.
30  *
31  * Based on the primitives given in the rte_ring library. Designed to be
32  * used inside software eventdev implementations and by applications
33  * directly as needed.
34  */
35 struct rte_event_ring {
36         struct rte_ring r;
37 };
38
39 /**
40  * Returns the number of events in the ring
41  *
42  * @param r
43  *   pointer to the event ring
44  * @return
45  *   the number of events in the ring
46  */
47 static __rte_always_inline unsigned int
48 rte_event_ring_count(const struct rte_event_ring *r)
49 {
50         return rte_ring_count(&r->r);
51 }
52
53 /**
54  * Returns the amount of free space in the ring
55  *
56  * @param r
57  *   pointer to the event ring
58  * @return
59  *   the number of free slots in the ring, i.e. the number of events that
60  *   can be successfully enqueued before dequeue must be called
61  */
62 static __rte_always_inline unsigned int
63 rte_event_ring_free_count(const struct rte_event_ring *r)
64 {
65         return rte_ring_free_count(&r->r);
66 }
67
68 /**
69  * Enqueue a set of events onto a ring
70  *
71  * Note: this API enqueues by copying the events themselves onto the ring,
72  * rather than just placing a pointer to each event onto the ring. This
73  * means that statically-allocated events can safely be enqueued by this
74  * API.
75  *
76  * @param r
77  *   pointer to the event ring
78  * @param events
79  *   pointer to an array of struct rte_event objects
80  * @param n
81  *   number of events in the array to enqueue
82  * @param free_space
83  *   if non-null, is updated to indicate the amount of free space in the
84  *   ring once the enqueue has completed.
85  * @return
86  *   the number of elements, n', enqueued to the ring, 0 <= n' <= n
87  */
88 static __rte_always_inline unsigned int
89 rte_event_ring_enqueue_burst(struct rte_event_ring *r,
90                 const struct rte_event *events,
91                 unsigned int n, uint16_t *free_space)
92 {
93         unsigned int num;
94         uint32_t space;
95
96         num = rte_ring_enqueue_burst_elem(&r->r, events,
97                                 sizeof(struct rte_event), n,
98                                 &space);
99
100         if (free_space != NULL)
101                 *free_space = space;
102
103         return num;
104 }
105
106 /**
107  * Dequeue a set of events from a ring
108  *
109  * Note: this API does not work with pointers to events, rather it copies
110  * the events themselves to the destination ``events`` buffer.
111  *
112  * @param r
113  *   pointer to the event ring
114  * @param events
115  *   pointer to an array to hold the struct rte_event objects
116  * @param n
117  *   number of events that can be held in the ``events`` array
118  * @param available
119  *   if non-null, is updated to indicate the number of events remaining in
120  *   the ring once the dequeue has completed
121  * @return
122  *   the number of elements, n', dequeued from the ring, 0 <= n' <= n
123  */
124 static __rte_always_inline unsigned int
125 rte_event_ring_dequeue_burst(struct rte_event_ring *r,
126                 struct rte_event *events,
127                 unsigned int n, uint16_t *available)
128 {
129         unsigned int num;
130         uint32_t remaining;
131
132         num = rte_ring_dequeue_burst_elem(&r->r, events,
133                                 sizeof(struct rte_event), n,
134                                 &remaining);
135
136         if (available != NULL)
137                 *available = remaining;
138
139         return num;
140 }
141
142 /*
143  * Initializes an already-allocated ring structure
144  *
145  * @param r
146  *   pointer to the ring memory to be initialized
147  * @param name
148  *   name to be given to the ring
149  * @param count
150  *   the number of elements to be stored in the ring. If the flag
151  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
152  *   usable space in the ring will be ``count - 1`` entries. If the flag
153  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
154  *   limit - 1, and the usable space will be exactly that requested.
155  * @param flags
156  *   An OR of the following:
157  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
158  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
159  *      is "single-producer". Otherwise, it is "multi-producers".
160  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
161  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
162  *      is "single-consumer". Otherwise, it is "multi-consumers".
163  *    - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
164  *      be taken as the exact usable size of the ring, and as such does not
165  *      need to be a power of 2. The underlying ring memory should be a
166  *      power-of-2 size greater than the count value.
167  * @return
168  *   0 on success, or a negative value on error.
169  */
170 int
171 rte_event_ring_init(struct rte_event_ring *r, const char *name,
172         unsigned int count, unsigned int flags);
173
174 /*
175  * Create an event ring structure
176  *
177  * This function allocates memory and initializes an event ring inside that
178  * memory.
179  *
180  * @param name
181  *   name to be given to the ring
182  * @param count
183  *   the number of elements to be stored in the ring. If the flag
184  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
185  *   usable space in the ring will be ``count - 1`` entries. If the flag
186  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
187  *   limit - 1, and the usable space will be exactly that requested.
188  * @param socket_id
189  *   The *socket_id* argument is the socket identifier in case of
190  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
191  *   constraint for the reserved zone.
192  * @param flags
193  *   An OR of the following:
194  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
195  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
196  *      is "single-producer". Otherwise, it is "multi-producers".
197  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
198  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
199  *      is "single-consumer". Otherwise, it is "multi-consumers".
200  *    - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
201  *      be taken as the exact usable size of the ring, and as such does not
202  *      need to be a power of 2. The underlying ring memory should be a
203  *      power-of-2 size greater than the count value.
204  * @return
205  *   On success, the pointer to the new allocated ring. NULL on error with
206  *    rte_errno set appropriately. Possible errno values include:
207  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
208  *    - E_RTE_SECONDARY - function was called from a secondary process instance
209  *    - EINVAL - count provided is not a power of 2
210  *    - ENOSPC - the maximum number of memzones has already been allocated
211  *    - EEXIST - a memzone with the same name already exists
212  *    - ENOMEM - no appropriate memory area found in which to create memzone
213  */
214 struct rte_event_ring *
215 rte_event_ring_create(const char *name, unsigned int count, int socket_id,
216                 unsigned int flags);
217
218 /**
219  * Search for an event ring based on its name
220  *
221  * @param name
222  *   The name of the ring.
223  * @return
224  *   The pointer to the ring matching the name, or NULL if not found,
225  *   with rte_errno set appropriately. Possible rte_errno values include:
226  *    - ENOENT - required entry not available to return.
227  */
228 struct rte_event_ring *
229 rte_event_ring_lookup(const char *name);
230
231 /**
232  * De-allocate all memory used by the ring.
233  *
234  * @param r
235  *   Ring to free
236  */
237 void
238 rte_event_ring_free(struct rte_event_ring *r);
239
240 /**
241  * Return the size of the event ring.
242  *
243  * @param r
244  *   A pointer to the ring structure.
245  * @return
246  *   The size of the data store used by the ring.
247  *   NOTE: this is not the same as the usable space in the ring. To query that
248  *   use ``rte_ring_get_capacity()``.
249  */
250 static inline unsigned int
251 rte_event_ring_get_size(const struct rte_event_ring *r)
252 {
253         return rte_ring_get_size(&r->r);
254 }
255
256 /**
257  * Return the number of elements which can be stored in the event ring.
258  *
259  * @param r
260  *   A pointer to the ring structure.
261  * @return
262  *   The usable size of the ring.
263  */
264 static inline unsigned int
265 rte_event_ring_get_capacity(const struct rte_event_ring *r)
266 {
267         return rte_ring_get_capacity(&r->r);
268 }
269 #endif