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