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 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdint.h> 22 23 #include <rte_common.h> 24 #include <rte_ring.h> 25 #include <rte_ring_elem.h> 26 #include "rte_eventdev.h" 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 * Enqueue a set of events onto a ring 72 * 73 * Note: this API enqueues by copying the events themselves onto the ring, 74 * rather than just placing a pointer to each event onto the ring. This 75 * means that statically-allocated events can safely be enqueued by this 76 * API. 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 * number of events in the array to enqueue 84 * @param free_space 85 * if non-null, is updated to indicate the amount of free space in the 86 * ring once the enqueue has completed. 87 * @return 88 * the number of elements, n', enqueued to the ring, 0 <= n' <= n 89 */ 90 static __rte_always_inline unsigned int 91 rte_event_ring_enqueue_burst(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_burst_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 elements, n', dequeued from the ring, 0 <= n' <= n 125 */ 126 static __rte_always_inline unsigned int 127 rte_event_ring_dequeue_burst(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_burst_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 * Initializes an already-allocated ring structure 146 * 147 * @param r 148 * pointer to the ring memory to be initialized 149 * @param name 150 * name to be given to the ring 151 * @param count 152 * the number of elements to be stored in the ring. If the flag 153 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 154 * usable space in the ring will be ``count - 1`` entries. If the flag 155 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 156 * limit - 1, and the usable space will be exactly that requested. 157 * @param flags 158 * An OR of the following: 159 * - RING_F_SP_ENQ: If this flag is set, the default behavior when 160 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 161 * is "single-producer". Otherwise, it is "multi-producers". 162 * - RING_F_SC_DEQ: If this flag is set, the default behavior when 163 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 164 * is "single-consumer". Otherwise, it is "multi-consumers". 165 * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 166 * be taken as the exact usable size of the ring, and as such does not 167 * need to be a power of 2. The underlying ring memory should be a 168 * power-of-2 size greater than the count value. 169 * @return 170 * 0 on success, or a negative value on error. 171 */ 172 int 173 rte_event_ring_init(struct rte_event_ring *r, const char *name, 174 unsigned int count, unsigned int flags); 175 176 /* 177 * Create an event ring structure 178 * 179 * This function allocates memory and initializes an event ring inside that 180 * memory. 181 * 182 * @param name 183 * name to be given to the ring 184 * @param count 185 * the number of elements to be stored in the ring. If the flag 186 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 187 * usable space in the ring will be ``count - 1`` entries. If the flag 188 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 189 * limit - 1, and the usable space will be exactly that requested. 190 * @param socket_id 191 * The *socket_id* argument is the socket identifier in case of 192 * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA 193 * constraint for the reserved zone. 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 * On success, the pointer to the new allocated ring. NULL on error with 208 * rte_errno set appropriately. Possible errno values include: 209 * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 210 * - E_RTE_SECONDARY - function was called from a secondary process instance 211 * - EINVAL - count provided is not a power of 2 212 * - ENOSPC - the maximum number of memzones has already been allocated 213 * - EEXIST - a memzone with the same name already exists 214 * - ENOMEM - no appropriate memory area found in which to create memzone 215 */ 216 struct rte_event_ring * 217 rte_event_ring_create(const char *name, unsigned int count, int socket_id, 218 unsigned int flags); 219 220 /** 221 * Search for an event ring based on its name 222 * 223 * @param name 224 * The name of the ring. 225 * @return 226 * The pointer to the ring matching the name, or NULL if not found, 227 * with rte_errno set appropriately. Possible rte_errno values include: 228 * - ENOENT - required entry not available to return. 229 */ 230 struct rte_event_ring * 231 rte_event_ring_lookup(const char *name); 232 233 /** 234 * De-allocate all memory used by the ring. 235 * 236 * @param r 237 * Ring to free 238 */ 239 void 240 rte_event_ring_free(struct rte_event_ring *r); 241 242 /** 243 * Return the size of the event ring. 244 * 245 * @param r 246 * A pointer to the ring structure. 247 * @return 248 * The size of the data store used by the ring. 249 * NOTE: this is not the same as the usable space in the ring. To query that 250 * use ``rte_ring_get_capacity()``. 251 */ 252 static inline unsigned int 253 rte_event_ring_get_size(const struct rte_event_ring *r) 254 { 255 return rte_ring_get_size(&r->r); 256 } 257 258 /** 259 * Return the number of elements which can be stored in the event ring. 260 * 261 * @param r 262 * A pointer to the ring structure. 263 * @return 264 * The usable size of the ring. 265 */ 266 static inline unsigned int 267 rte_event_ring_get_capacity(const struct rte_event_ring *r) 268 { 269 return rte_ring_get_capacity(&r->r); 270 } 271 272 #ifdef __cplusplus 273 } 274 #endif 275 276 #endif 277