xref: /dpdk/lib/eventdev/rte_event_ring.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2016-2017 Intel Corporation
399a2dd95SBruce Richardson  * Copyright(c) 2019 Arm Limited
499a2dd95SBruce Richardson  */
599a2dd95SBruce Richardson 
699a2dd95SBruce Richardson /**
799a2dd95SBruce Richardson  * @file
899a2dd95SBruce Richardson  * RTE Event Ring
999a2dd95SBruce Richardson  *
1099a2dd95SBruce Richardson  * This provides a ring implementation for passing rte_event structures
1199a2dd95SBruce Richardson  * from one core to another.
1299a2dd95SBruce Richardson  */
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson #ifndef _RTE_EVENT_RING_
1599a2dd95SBruce Richardson #define _RTE_EVENT_RING_
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson #include <stdint.h>
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson #include <rte_common.h>
2099a2dd95SBruce Richardson #include <rte_ring.h>
2199a2dd95SBruce Richardson #include <rte_ring_elem.h>
2299a2dd95SBruce Richardson #include "rte_eventdev.h"
2399a2dd95SBruce Richardson 
24*719834a6SMattias Rönnblom #ifdef __cplusplus
25*719834a6SMattias Rönnblom extern "C" {
26*719834a6SMattias Rönnblom #endif
27*719834a6SMattias Rönnblom 
2899a2dd95SBruce Richardson #define RTE_TAILQ_EVENT_RING_NAME "RTE_EVENT_RING"
2999a2dd95SBruce Richardson 
3099a2dd95SBruce Richardson /**
3199a2dd95SBruce Richardson  * Generic ring structure for passing rte_event objects from core to core.
3299a2dd95SBruce Richardson  *
3399a2dd95SBruce Richardson  * Based on the primitives given in the rte_ring library. Designed to be
3499a2dd95SBruce Richardson  * used inside software eventdev implementations and by applications
3599a2dd95SBruce Richardson  * directly as needed.
3699a2dd95SBruce Richardson  */
3799a2dd95SBruce Richardson struct rte_event_ring {
3899a2dd95SBruce Richardson 	struct rte_ring r;
3999a2dd95SBruce Richardson };
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson /**
4299a2dd95SBruce Richardson  * Returns the number of events in the ring
4399a2dd95SBruce Richardson  *
4499a2dd95SBruce Richardson  * @param r
4599a2dd95SBruce Richardson  *   pointer to the event ring
4699a2dd95SBruce Richardson  * @return
4799a2dd95SBruce Richardson  *   the number of events in the ring
4899a2dd95SBruce Richardson  */
4999a2dd95SBruce Richardson static __rte_always_inline unsigned int
5099a2dd95SBruce Richardson rte_event_ring_count(const struct rte_event_ring *r)
5199a2dd95SBruce Richardson {
5299a2dd95SBruce Richardson 	return rte_ring_count(&r->r);
5399a2dd95SBruce Richardson }
5499a2dd95SBruce Richardson 
5599a2dd95SBruce Richardson /**
5699a2dd95SBruce Richardson  * Returns the amount of free space in the ring
5799a2dd95SBruce Richardson  *
5899a2dd95SBruce Richardson  * @param r
5999a2dd95SBruce Richardson  *   pointer to the event ring
6099a2dd95SBruce Richardson  * @return
6199a2dd95SBruce Richardson  *   the number of free slots in the ring, i.e. the number of events that
6299a2dd95SBruce Richardson  *   can be successfully enqueued before dequeue must be called
6399a2dd95SBruce Richardson  */
6499a2dd95SBruce Richardson static __rte_always_inline unsigned int
6599a2dd95SBruce Richardson rte_event_ring_free_count(const struct rte_event_ring *r)
6699a2dd95SBruce Richardson {
6799a2dd95SBruce Richardson 	return rte_ring_free_count(&r->r);
6899a2dd95SBruce Richardson }
6999a2dd95SBruce Richardson 
707edf09eaSMattias Rönnblom 
717edf09eaSMattias Rönnblom /**
727edf09eaSMattias Rönnblom  * Enqueue several objects on a ring.
737edf09eaSMattias Rönnblom  *
747edf09eaSMattias Rönnblom  * This function calls the multi-producer or the single-producer
757edf09eaSMattias Rönnblom  * version depending on the default behavior that was specified at
767edf09eaSMattias Rönnblom  * ring creation time (see flags).
777edf09eaSMattias Rönnblom  *
787edf09eaSMattias Rönnblom  * @param r
797edf09eaSMattias Rönnblom  *   pointer to the event ring
807edf09eaSMattias Rönnblom  * @param events
817edf09eaSMattias Rönnblom  *   pointer to an array of struct rte_event objects
827edf09eaSMattias Rönnblom  * @param n
837edf09eaSMattias Rönnblom  *   The number of events in the array to enqueue
847edf09eaSMattias Rönnblom  * @param free_space
857edf09eaSMattias Rönnblom  *   if non-NULL, returns the amount of space in the ring after the
867edf09eaSMattias Rönnblom  *   enqueue operation has completed
877edf09eaSMattias Rönnblom  * @return
887edf09eaSMattias Rönnblom  *   the number of objects enqueued, either 0 or n
897edf09eaSMattias Rönnblom  */
907edf09eaSMattias Rönnblom static __rte_always_inline unsigned int
917edf09eaSMattias Rönnblom rte_event_ring_enqueue_bulk(struct rte_event_ring *r,
927edf09eaSMattias Rönnblom 			    const struct rte_event *events,
937edf09eaSMattias Rönnblom 			    unsigned int n, uint16_t *free_space)
947edf09eaSMattias Rönnblom {
957edf09eaSMattias Rönnblom 	unsigned int num;
967edf09eaSMattias Rönnblom 	uint32_t space;
977edf09eaSMattias Rönnblom 
987edf09eaSMattias Rönnblom 	num = rte_ring_enqueue_bulk_elem(&r->r, events,
997edf09eaSMattias Rönnblom 					 sizeof(struct rte_event), n,
1007edf09eaSMattias Rönnblom 					 &space);
1017edf09eaSMattias Rönnblom 
1027edf09eaSMattias Rönnblom 	if (free_space != NULL)
1037edf09eaSMattias Rönnblom 		*free_space = space;
1047edf09eaSMattias Rönnblom 
1057edf09eaSMattias Rönnblom 	return num;
1067edf09eaSMattias Rönnblom }
1077edf09eaSMattias Rönnblom 
1087edf09eaSMattias Rönnblom /**
1097edf09eaSMattias Rönnblom  * Dequeue a set of events from a ring
1107edf09eaSMattias Rönnblom  *
1117edf09eaSMattias Rönnblom  * Note: this API does not work with pointers to events, rather it copies
1127edf09eaSMattias Rönnblom  * the events themselves to the destination ``events`` buffer.
1137edf09eaSMattias Rönnblom  *
1147edf09eaSMattias Rönnblom  * @param r
1157edf09eaSMattias Rönnblom  *   pointer to the event ring
1167edf09eaSMattias Rönnblom  * @param events
1177edf09eaSMattias Rönnblom  *   pointer to an array to hold the struct rte_event objects
1187edf09eaSMattias Rönnblom  * @param n
1197edf09eaSMattias Rönnblom  *   number of events that can be held in the ``events`` array
1207edf09eaSMattias Rönnblom  * @param available
1217edf09eaSMattias Rönnblom  *   if non-null, is updated to indicate the number of events remaining in
1227edf09eaSMattias Rönnblom  *   the ring once the dequeue has completed
1237edf09eaSMattias Rönnblom  * @return
1247edf09eaSMattias Rönnblom  *   the number of objects dequeued, either 0 or n
1257edf09eaSMattias Rönnblom  */
1267edf09eaSMattias Rönnblom static __rte_always_inline unsigned int
1277edf09eaSMattias Rönnblom rte_event_ring_dequeue_bulk(struct rte_event_ring *r,
1287edf09eaSMattias Rönnblom 			     struct rte_event *events,
1297edf09eaSMattias Rönnblom 			     unsigned int n, uint16_t *available)
1307edf09eaSMattias Rönnblom {
1317edf09eaSMattias Rönnblom 	unsigned int num;
1327edf09eaSMattias Rönnblom 	uint32_t remaining;
1337edf09eaSMattias Rönnblom 
1347edf09eaSMattias Rönnblom 	num = rte_ring_dequeue_bulk_elem(&r->r, events,
1357edf09eaSMattias Rönnblom 					 sizeof(struct rte_event), n,
1367edf09eaSMattias Rönnblom 					 &remaining);
1377edf09eaSMattias Rönnblom 
1387edf09eaSMattias Rönnblom 	if (available != NULL)
1397edf09eaSMattias Rönnblom 		*available = remaining;
1407edf09eaSMattias Rönnblom 
1417edf09eaSMattias Rönnblom 	return num;
1427edf09eaSMattias Rönnblom }
1437edf09eaSMattias Rönnblom 
14499a2dd95SBruce Richardson /**
14599a2dd95SBruce Richardson  * Enqueue a set of events onto a ring
14699a2dd95SBruce Richardson  *
14799a2dd95SBruce Richardson  * Note: this API enqueues by copying the events themselves onto the ring,
14899a2dd95SBruce Richardson  * rather than just placing a pointer to each event onto the ring. This
14999a2dd95SBruce Richardson  * means that statically-allocated events can safely be enqueued by this
15099a2dd95SBruce Richardson  * API.
15199a2dd95SBruce Richardson  *
15299a2dd95SBruce Richardson  * @param r
15399a2dd95SBruce Richardson  *   pointer to the event ring
15499a2dd95SBruce Richardson  * @param events
15599a2dd95SBruce Richardson  *   pointer to an array of struct rte_event objects
15699a2dd95SBruce Richardson  * @param n
15799a2dd95SBruce Richardson  *   number of events in the array to enqueue
15899a2dd95SBruce Richardson  * @param free_space
15999a2dd95SBruce Richardson  *   if non-null, is updated to indicate the amount of free space in the
16099a2dd95SBruce Richardson  *   ring once the enqueue has completed.
16199a2dd95SBruce Richardson  * @return
16299a2dd95SBruce Richardson  *   the number of elements, n', enqueued to the ring, 0 <= n' <= n
16399a2dd95SBruce Richardson  */
16499a2dd95SBruce Richardson static __rte_always_inline unsigned int
16599a2dd95SBruce Richardson rte_event_ring_enqueue_burst(struct rte_event_ring *r,
16699a2dd95SBruce Richardson 		const struct rte_event *events,
16799a2dd95SBruce Richardson 		unsigned int n, uint16_t *free_space)
16899a2dd95SBruce Richardson {
16999a2dd95SBruce Richardson 	unsigned int num;
17099a2dd95SBruce Richardson 	uint32_t space;
17199a2dd95SBruce Richardson 
17299a2dd95SBruce Richardson 	num = rte_ring_enqueue_burst_elem(&r->r, events,
17399a2dd95SBruce Richardson 				sizeof(struct rte_event), n,
17499a2dd95SBruce Richardson 				&space);
17599a2dd95SBruce Richardson 
17699a2dd95SBruce Richardson 	if (free_space != NULL)
17799a2dd95SBruce Richardson 		*free_space = space;
17899a2dd95SBruce Richardson 
17999a2dd95SBruce Richardson 	return num;
18099a2dd95SBruce Richardson }
18199a2dd95SBruce Richardson 
18299a2dd95SBruce Richardson /**
18399a2dd95SBruce Richardson  * Dequeue a set of events from a ring
18499a2dd95SBruce Richardson  *
18599a2dd95SBruce Richardson  * Note: this API does not work with pointers to events, rather it copies
18699a2dd95SBruce Richardson  * the events themselves to the destination ``events`` buffer.
18799a2dd95SBruce Richardson  *
18899a2dd95SBruce Richardson  * @param r
18999a2dd95SBruce Richardson  *   pointer to the event ring
19099a2dd95SBruce Richardson  * @param events
19199a2dd95SBruce Richardson  *   pointer to an array to hold the struct rte_event objects
19299a2dd95SBruce Richardson  * @param n
19399a2dd95SBruce Richardson  *   number of events that can be held in the ``events`` array
19499a2dd95SBruce Richardson  * @param available
19599a2dd95SBruce Richardson  *   if non-null, is updated to indicate the number of events remaining in
19699a2dd95SBruce Richardson  *   the ring once the dequeue has completed
19799a2dd95SBruce Richardson  * @return
19899a2dd95SBruce Richardson  *   the number of elements, n', dequeued from the ring, 0 <= n' <= n
19999a2dd95SBruce Richardson  */
20099a2dd95SBruce Richardson static __rte_always_inline unsigned int
20199a2dd95SBruce Richardson rte_event_ring_dequeue_burst(struct rte_event_ring *r,
20299a2dd95SBruce Richardson 		struct rte_event *events,
20399a2dd95SBruce Richardson 		unsigned int n, uint16_t *available)
20499a2dd95SBruce Richardson {
20599a2dd95SBruce Richardson 	unsigned int num;
20699a2dd95SBruce Richardson 	uint32_t remaining;
20799a2dd95SBruce Richardson 
20899a2dd95SBruce Richardson 	num = rte_ring_dequeue_burst_elem(&r->r, events,
20999a2dd95SBruce Richardson 				sizeof(struct rte_event), n,
21099a2dd95SBruce Richardson 				&remaining);
21199a2dd95SBruce Richardson 
21299a2dd95SBruce Richardson 	if (available != NULL)
21399a2dd95SBruce Richardson 		*available = remaining;
21499a2dd95SBruce Richardson 
21599a2dd95SBruce Richardson 	return num;
21699a2dd95SBruce Richardson }
21799a2dd95SBruce Richardson 
21899a2dd95SBruce Richardson /*
21999a2dd95SBruce Richardson  * Initializes an already-allocated ring structure
22099a2dd95SBruce Richardson  *
22199a2dd95SBruce Richardson  * @param r
22299a2dd95SBruce Richardson  *   pointer to the ring memory to be initialized
22399a2dd95SBruce Richardson  * @param name
22499a2dd95SBruce Richardson  *   name to be given to the ring
22599a2dd95SBruce Richardson  * @param count
22699a2dd95SBruce Richardson  *   the number of elements to be stored in the ring. If the flag
22799a2dd95SBruce Richardson  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
22899a2dd95SBruce Richardson  *   usable space in the ring will be ``count - 1`` entries. If the flag
22999a2dd95SBruce Richardson  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
23099a2dd95SBruce Richardson  *   limit - 1, and the usable space will be exactly that requested.
23199a2dd95SBruce Richardson  * @param flags
23299a2dd95SBruce Richardson  *   An OR of the following:
23399a2dd95SBruce Richardson  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
23499a2dd95SBruce Richardson  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
23599a2dd95SBruce Richardson  *      is "single-producer". Otherwise, it is "multi-producers".
23699a2dd95SBruce Richardson  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
23799a2dd95SBruce Richardson  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
23899a2dd95SBruce Richardson  *      is "single-consumer". Otherwise, it is "multi-consumers".
23999a2dd95SBruce Richardson  *    - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
24099a2dd95SBruce Richardson  *      be taken as the exact usable size of the ring, and as such does not
24199a2dd95SBruce Richardson  *      need to be a power of 2. The underlying ring memory should be a
24299a2dd95SBruce Richardson  *      power-of-2 size greater than the count value.
24399a2dd95SBruce Richardson  * @return
24499a2dd95SBruce Richardson  *   0 on success, or a negative value on error.
24599a2dd95SBruce Richardson  */
24699a2dd95SBruce Richardson int
24799a2dd95SBruce Richardson rte_event_ring_init(struct rte_event_ring *r, const char *name,
24899a2dd95SBruce Richardson 	unsigned int count, unsigned int flags);
24999a2dd95SBruce Richardson 
25099a2dd95SBruce Richardson /*
25199a2dd95SBruce Richardson  * Create an event ring structure
25299a2dd95SBruce Richardson  *
25399a2dd95SBruce Richardson  * This function allocates memory and initializes an event ring inside that
25499a2dd95SBruce Richardson  * memory.
25599a2dd95SBruce Richardson  *
25699a2dd95SBruce Richardson  * @param name
25799a2dd95SBruce Richardson  *   name to be given to the ring
25899a2dd95SBruce Richardson  * @param count
25999a2dd95SBruce Richardson  *   the number of elements to be stored in the ring. If the flag
26099a2dd95SBruce Richardson  *   ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual
26199a2dd95SBruce Richardson  *   usable space in the ring will be ``count - 1`` entries. If the flag
26299a2dd95SBruce Richardson  *   ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size
26399a2dd95SBruce Richardson  *   limit - 1, and the usable space will be exactly that requested.
26499a2dd95SBruce Richardson  * @param socket_id
26599a2dd95SBruce Richardson  *   The *socket_id* argument is the socket identifier in case of
26699a2dd95SBruce Richardson  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
26799a2dd95SBruce Richardson  *   constraint for the reserved zone.
26899a2dd95SBruce Richardson  * @param flags
26999a2dd95SBruce Richardson  *   An OR of the following:
27099a2dd95SBruce Richardson  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
27199a2dd95SBruce Richardson  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
27299a2dd95SBruce Richardson  *      is "single-producer". Otherwise, it is "multi-producers".
27399a2dd95SBruce Richardson  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
27499a2dd95SBruce Richardson  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
27599a2dd95SBruce Richardson  *      is "single-consumer". Otherwise, it is "multi-consumers".
27699a2dd95SBruce Richardson  *    - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to
27799a2dd95SBruce Richardson  *      be taken as the exact usable size of the ring, and as such does not
27899a2dd95SBruce Richardson  *      need to be a power of 2. The underlying ring memory should be a
27999a2dd95SBruce Richardson  *      power-of-2 size greater than the count value.
28099a2dd95SBruce Richardson  * @return
28199a2dd95SBruce Richardson  *   On success, the pointer to the new allocated ring. NULL on error with
28299a2dd95SBruce Richardson  *    rte_errno set appropriately. Possible errno values include:
28399a2dd95SBruce Richardson  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
28499a2dd95SBruce Richardson  *    - E_RTE_SECONDARY - function was called from a secondary process instance
28599a2dd95SBruce Richardson  *    - EINVAL - count provided is not a power of 2
28699a2dd95SBruce Richardson  *    - ENOSPC - the maximum number of memzones has already been allocated
28799a2dd95SBruce Richardson  *    - EEXIST - a memzone with the same name already exists
28899a2dd95SBruce Richardson  *    - ENOMEM - no appropriate memory area found in which to create memzone
28999a2dd95SBruce Richardson  */
29099a2dd95SBruce Richardson struct rte_event_ring *
29199a2dd95SBruce Richardson rte_event_ring_create(const char *name, unsigned int count, int socket_id,
29299a2dd95SBruce Richardson 		unsigned int flags);
29399a2dd95SBruce Richardson 
29499a2dd95SBruce Richardson /**
29599a2dd95SBruce Richardson  * Search for an event ring based on its name
29699a2dd95SBruce Richardson  *
29799a2dd95SBruce Richardson  * @param name
29899a2dd95SBruce Richardson  *   The name of the ring.
29999a2dd95SBruce Richardson  * @return
30099a2dd95SBruce Richardson  *   The pointer to the ring matching the name, or NULL if not found,
30199a2dd95SBruce Richardson  *   with rte_errno set appropriately. Possible rte_errno values include:
30299a2dd95SBruce Richardson  *    - ENOENT - required entry not available to return.
30399a2dd95SBruce Richardson  */
30499a2dd95SBruce Richardson struct rte_event_ring *
30599a2dd95SBruce Richardson rte_event_ring_lookup(const char *name);
30699a2dd95SBruce Richardson 
30799a2dd95SBruce Richardson /**
30899a2dd95SBruce Richardson  * De-allocate all memory used by the ring.
30999a2dd95SBruce Richardson  *
31099a2dd95SBruce Richardson  * @param r
311448e01f1SStephen Hemminger  *   Pointer to ring to created with rte_event_ring_create().
312448e01f1SStephen Hemminger  *   If r is NULL, no operation is performed.
31399a2dd95SBruce Richardson  */
31499a2dd95SBruce Richardson void
31599a2dd95SBruce Richardson rte_event_ring_free(struct rte_event_ring *r);
31699a2dd95SBruce Richardson 
31799a2dd95SBruce Richardson /**
31899a2dd95SBruce Richardson  * Return the size of the event ring.
31999a2dd95SBruce Richardson  *
32099a2dd95SBruce Richardson  * @param r
32199a2dd95SBruce Richardson  *   A pointer to the ring structure.
32299a2dd95SBruce Richardson  * @return
32399a2dd95SBruce Richardson  *   The size of the data store used by the ring.
32499a2dd95SBruce Richardson  *   NOTE: this is not the same as the usable space in the ring. To query that
32599a2dd95SBruce Richardson  *   use ``rte_ring_get_capacity()``.
32699a2dd95SBruce Richardson  */
32799a2dd95SBruce Richardson static inline unsigned int
32899a2dd95SBruce Richardson rte_event_ring_get_size(const struct rte_event_ring *r)
32999a2dd95SBruce Richardson {
33099a2dd95SBruce Richardson 	return rte_ring_get_size(&r->r);
33199a2dd95SBruce Richardson }
33299a2dd95SBruce Richardson 
33399a2dd95SBruce Richardson /**
33499a2dd95SBruce Richardson  * Return the number of elements which can be stored in the event ring.
33599a2dd95SBruce Richardson  *
33699a2dd95SBruce Richardson  * @param r
33799a2dd95SBruce Richardson  *   A pointer to the ring structure.
33899a2dd95SBruce Richardson  * @return
33999a2dd95SBruce Richardson  *   The usable size of the ring.
34099a2dd95SBruce Richardson  */
34199a2dd95SBruce Richardson static inline unsigned int
34299a2dd95SBruce Richardson rte_event_ring_get_capacity(const struct rte_event_ring *r)
34399a2dd95SBruce Richardson {
34499a2dd95SBruce Richardson 	return rte_ring_get_capacity(&r->r);
34599a2dd95SBruce Richardson }
3462c552933SBrian Dooley 
3472c552933SBrian Dooley #ifdef __cplusplus
3482c552933SBrian Dooley }
3492c552933SBrian Dooley #endif
3502c552933SBrian Dooley 
35199a2dd95SBruce Richardson #endif
352