ea9b68854ccc9104fd8e783a98427b790f74fecd
[deb_dpdk.git] / lib / librte_eventdev / rte_event_ring.h
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /**
34  * @file
35  * RTE Event Ring
36  *
37  * This provides a ring implementation for passing rte_event structures
38  * from one core to another.
39  */
40
41 #ifndef _RTE_EVENT_RING_
42 #define _RTE_EVENT_RING_
43
44 #include <stdint.h>
45
46 #include <rte_common.h>
47 #include <rte_memory.h>
48 #include <rte_malloc.h>
49 #include <rte_ring.h>
50 #include "rte_eventdev.h"
51
52 #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING"
53
54 /**
55  * Generic ring structure for passing rte_event objects from core to core.
56  *
57  * Based on the primitives given in the rte_ring library. Designed to be
58  * used inside software eventdev implementations and by applications
59  * directly as needed.
60  */
61 struct rte_event_ring {
62         struct rte_ring r;
63 };
64
65 /**
66  * Returns the number of events in the ring
67  *
68  * @param r
69  *   pointer to the event ring
70  * @return
71  *   the number of events in the ring
72  */
73 static __rte_always_inline unsigned int
74 rte_event_ring_count(const struct rte_event_ring *r)
75 {
76         return rte_ring_count(&r->r);
77 }
78
79 /**
80  * Returns the amount of free space in the ring
81  *
82  * @param r
83  *   pointer to the event ring
84  * @return
85  *   the number of free slots in the ring, i.e. the number of events that
86  *   can be successfully enqueued before dequeue must be called
87  */
88 static __rte_always_inline unsigned int
89 rte_event_ring_free_count(const struct rte_event_ring *r)
90 {
91         return rte_ring_free_count(&r->r);
92 }
93
94 /**
95  * Enqueue a set of events onto a ring
96  *
97  * Note: this API enqueues by copying the events themselves onto the ring,
98  * rather than just placing a pointer to each event onto the ring. This
99  * means that statically-allocated events can safely be enqueued by this
100  * API.
101  *
102  * @param r
103  *   pointer to the event ring
104  * @param events
105  *   pointer to an array of struct rte_event objects
106  * @param n
107  *   number of events in the array to enqueue
108  * @param free_space
109  *   if non-null, is updated to indicate the amount of free space in the
110  *   ring once the enqueue has completed.
111  * @return
112  *   the number of elements, n', enqueued to the ring, 0 <= n' <= n
113  */
114 static __rte_always_inline unsigned int
115 rte_event_ring_enqueue_burst(struct rte_event_ring *r,
116                 const struct rte_event *events,
117                 unsigned int n, uint16_t *free_space)
118 {
119         uint32_t prod_head, prod_next;
120         uint32_t free_entries;
121
122         n = __rte_ring_move_prod_head(&r->r, r->r.prod.single, n,
123                         RTE_RING_QUEUE_VARIABLE,
124                         &prod_head, &prod_next, &free_entries);
125         if (n == 0)
126                 goto end;
127
128         ENQUEUE_PTRS(&r->r, &r[1], prod_head, events, n, struct rte_event);
129         rte_smp_wmb();
130
131         update_tail(&r->r.prod, prod_head, prod_next, 1);
132 end:
133         if (free_space != NULL)
134                 *free_space = free_entries - n;
135         return n;
136 }
137
138 /**
139  * Dequeue a set of events from a ring
140  *
141  * Note: this API does not work with pointers to events, rather it copies
142  * the events themselves to the destination ``events`` buffer.
143  *
144  * @param r
145  *   pointer to the event ring
146  * @param events
147  *   pointer to an array to hold the struct rte_event objects
148  * @param n
149  *   number of events that can be held in the ``events`` array
150  * @param available
151  *   if non-null, is updated to indicate the number of events remaining in
152  *   the ring once the dequeue has completed
153  * @return
154  *   the number of elements, n', dequeued from the ring, 0 <= n' <= n
155  */
156 static __rte_always_inline unsigned int
157 rte_event_ring_dequeue_burst(struct rte_event_ring *r,
158                 struct rte_event *events,
159                 unsigned int n, uint16_t *available)
160 {
161         uint32_t cons_head, cons_next;
162         uint32_t entries;
163
164         n = __rte_ring_move_cons_head(&r->r, r->r.cons.single, n,
165                         RTE_RING_QUEUE_VARIABLE,
166                         &cons_head, &cons_next, &entries);
167         if (n == 0)
168                 goto end;
169
170         DEQUEUE_PTRS(&r->r, &r[1], cons_head, events, n, struct rte_event);
171         rte_smp_rmb();
172
173         update_tail(&r->r.cons, cons_head, cons_next, 1);
174
175 end:
176         if (available != NULL)
177                 *available = entries - n;
178         return n;
179 }
180
181 /*
182  * Initializes an already-allocated ring structure
183  *
184  * @param r
185  *   pointer to the ring memory to be initialized
186  * @param name
187  *   name to be given to the ring
188  * @param count
189  *   the number of elements to be stored in the ring. If the flag
190  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
191  *   usable space in the ring will be ``count - 1`` entries. If the flag
192  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
193  *   limit - 1, and the usable space will be exactly that requested.
194  * @param flags
195  *   An OR of the following:
196  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
197  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
198  *      is "single-producer". Otherwise, it is "multi-producers".
199  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
200  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
201  *      is "single-consumer". Otherwise, it is "multi-consumers".
202  *    - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
203  *      be taken as the exact usable size of the ring, and as such does not
204  *      need to be a power of 2. The underlying ring memory should be a
205  *      power-of-2 size greater than the count value.
206  * @return
207  *   0 on success, or a negative value on error.
208  */
209 int
210 rte_event_ring_init(struct rte_event_ring *r, const char *name,
211         unsigned int count, unsigned int flags);
212
213 /*
214  * Create an event ring structure
215  *
216  * This function allocates memory and initializes an event ring inside that
217  * memory.
218  *
219  * @param name
220  *   name to be given to the ring
221  * @param count
222  *   the number of elements to be stored in the ring. If the flag
223  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
224  *   usable space in the ring will be ``count - 1`` entries. If the flag
225  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
226  *   limit - 1, and the usable space will be exactly that requested.
227  * @param socket_id
228  *   The *socket_id* argument is the socket identifier in case of
229  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
230  *   constraint for the reserved zone.
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  *   On success, the pointer to the new allocated ring. NULL on error with
245  *    rte_errno set appropriately. Possible errno values include:
246  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
247  *    - E_RTE_SECONDARY - function was called from a secondary process instance
248  *    - EINVAL - count provided is not a power of 2
249  *    - ENOSPC - the maximum number of memzones has already been allocated
250  *    - EEXIST - a memzone with the same name already exists
251  *    - ENOMEM - no appropriate memory area found in which to create memzone
252  */
253 struct rte_event_ring *
254 rte_event_ring_create(const char *name, unsigned int count, int socket_id,
255                 unsigned int flags);
256
257 /**
258  * Search for an event ring based on its name
259  *
260  * @param name
261  *   The name of the ring.
262  * @return
263  *   The pointer to the ring matching the name, or NULL if not found,
264  *   with rte_errno set appropriately. Possible rte_errno values include:
265  *    - ENOENT - required entry not available to return.
266  */
267 struct rte_event_ring *
268 rte_event_ring_lookup(const char *name);
269
270 /**
271  * De-allocate all memory used by the ring.
272  *
273  * @param r
274  *   Ring to free
275  */
276 void
277 rte_event_ring_free(struct rte_event_ring *r);
278
279 /**
280  * Return the size of the event ring.
281  *
282  * @param r
283  *   A pointer to the ring structure.
284  * @return
285  *   The size of the data store used by the ring.
286  *   NOTE: this is not the same as the usable space in the ring. To query that
287  *   use ``rte_ring_get_capacity()``.
288  */
289 static inline unsigned int
290 rte_event_ring_get_size(const struct rte_event_ring *r)
291 {
292         return rte_ring_get_size(&r->r);
293 }
294
295 /**
296  * Return the number of elements which can be stored in the event ring.
297  *
298  * @param r
299  *   A pointer to the ring structure.
300  * @return
301  *   The usable size of the ring.
302  */
303 static inline unsigned int
304 rte_event_ring_get_capacity(const struct rte_event_ring *r)
305 {
306         return rte_ring_get_capacity(&r->r);
307 }
308 #endif