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_ring.h> 21 #include <rte_ring_elem.h> 22 #include "rte_eventdev.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 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 /** 72 * Enqueue several objects on a ring. 73 * 74 * This function calls the multi-producer or the single-producer 75 * version depending on the default behavior that was specified at 76 * ring creation time (see flags). 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 * The number of events in the array to enqueue 84 * @param free_space 85 * if non-NULL, returns the amount of space in the ring after the 86 * enqueue operation has completed 87 * @return 88 * the number of objects enqueued, either 0 or n 89 */ 90 static __rte_always_inline unsigned int 91 rte_event_ring_enqueue_bulk(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_bulk_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 objects dequeued, either 0 or n 125 */ 126 static __rte_always_inline unsigned int 127 rte_event_ring_dequeue_bulk(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_bulk_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 * Enqueue a set of events onto a ring 146 * 147 * Note: this API enqueues by copying the events themselves onto the ring, 148 * rather than just placing a pointer to each event onto the ring. This 149 * means that statically-allocated events can safely be enqueued by this 150 * API. 151 * 152 * @param r 153 * pointer to the event ring 154 * @param events 155 * pointer to an array of struct rte_event objects 156 * @param n 157 * number of events in the array to enqueue 158 * @param free_space 159 * if non-null, is updated to indicate the amount of free space in the 160 * ring once the enqueue has completed. 161 * @return 162 * the number of elements, n', enqueued to the ring, 0 <= n' <= n 163 */ 164 static __rte_always_inline unsigned int 165 rte_event_ring_enqueue_burst(struct rte_event_ring *r, 166 const struct rte_event *events, 167 unsigned int n, uint16_t *free_space) 168 { 169 unsigned int num; 170 uint32_t space; 171 172 num = rte_ring_enqueue_burst_elem(&r->r, events, 173 sizeof(struct rte_event), n, 174 &space); 175 176 if (free_space != NULL) 177 *free_space = space; 178 179 return num; 180 } 181 182 /** 183 * Dequeue a set of events from a ring 184 * 185 * Note: this API does not work with pointers to events, rather it copies 186 * the events themselves to the destination ``events`` buffer. 187 * 188 * @param r 189 * pointer to the event ring 190 * @param events 191 * pointer to an array to hold the struct rte_event objects 192 * @param n 193 * number of events that can be held in the ``events`` array 194 * @param available 195 * if non-null, is updated to indicate the number of events remaining in 196 * the ring once the dequeue has completed 197 * @return 198 * the number of elements, n', dequeued from the ring, 0 <= n' <= n 199 */ 200 static __rte_always_inline unsigned int 201 rte_event_ring_dequeue_burst(struct rte_event_ring *r, 202 struct rte_event *events, 203 unsigned int n, uint16_t *available) 204 { 205 unsigned int num; 206 uint32_t remaining; 207 208 num = rte_ring_dequeue_burst_elem(&r->r, events, 209 sizeof(struct rte_event), n, 210 &remaining); 211 212 if (available != NULL) 213 *available = remaining; 214 215 return num; 216 } 217 218 /* 219 * Initializes an already-allocated ring structure 220 * 221 * @param r 222 * pointer to the ring memory to be initialized 223 * @param name 224 * name to be given to the ring 225 * @param count 226 * the number of elements to be stored in the ring. If the flag 227 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 228 * usable space in the ring will be ``count - 1`` entries. If the flag 229 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 230 * limit - 1, and the usable space will be exactly that requested. 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 * 0 on success, or a negative value on error. 245 */ 246 int 247 rte_event_ring_init(struct rte_event_ring *r, const char *name, 248 unsigned int count, unsigned int flags); 249 250 /* 251 * Create an event ring structure 252 * 253 * This function allocates memory and initializes an event ring inside that 254 * memory. 255 * 256 * @param name 257 * name to be given to the ring 258 * @param count 259 * the number of elements to be stored in the ring. If the flag 260 * ``RING_F_EXACT_SZ`` is not set, this must be a power of 2, and the actual 261 * usable space in the ring will be ``count - 1`` entries. If the flag 262 * ``RING_F_EXACT_SZ`` is set, the this can be any value up to the ring size 263 * limit - 1, and the usable space will be exactly that requested. 264 * @param socket_id 265 * The *socket_id* argument is the socket identifier in case of 266 * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA 267 * constraint for the reserved zone. 268 * @param flags 269 * An OR of the following: 270 * - RING_F_SP_ENQ: If this flag is set, the default behavior when 271 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 272 * is "single-producer". Otherwise, it is "multi-producers". 273 * - RING_F_SC_DEQ: If this flag is set, the default behavior when 274 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 275 * is "single-consumer". Otherwise, it is "multi-consumers". 276 * - RING_F_EXACT_SZ: If this flag is set, the ``count`` parameter is to 277 * be taken as the exact usable size of the ring, and as such does not 278 * need to be a power of 2. The underlying ring memory should be a 279 * power-of-2 size greater than the count value. 280 * @return 281 * On success, the pointer to the new allocated ring. NULL on error with 282 * rte_errno set appropriately. Possible errno values include: 283 * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 284 * - E_RTE_SECONDARY - function was called from a secondary process instance 285 * - EINVAL - count provided is not a power of 2 286 * - ENOSPC - the maximum number of memzones has already been allocated 287 * - EEXIST - a memzone with the same name already exists 288 * - ENOMEM - no appropriate memory area found in which to create memzone 289 */ 290 struct rte_event_ring * 291 rte_event_ring_create(const char *name, unsigned int count, int socket_id, 292 unsigned int flags); 293 294 /** 295 * Search for an event ring based on its name 296 * 297 * @param name 298 * The name of the ring. 299 * @return 300 * The pointer to the ring matching the name, or NULL if not found, 301 * with rte_errno set appropriately. Possible rte_errno values include: 302 * - ENOENT - required entry not available to return. 303 */ 304 struct rte_event_ring * 305 rte_event_ring_lookup(const char *name); 306 307 /** 308 * De-allocate all memory used by the ring. 309 * 310 * @param r 311 * Pointer to ring to created with rte_event_ring_create(). 312 * If r is NULL, no operation is performed. 313 */ 314 void 315 rte_event_ring_free(struct rte_event_ring *r); 316 317 /** 318 * Return the size of the event ring. 319 * 320 * @param r 321 * A pointer to the ring structure. 322 * @return 323 * The size of the data store used by the ring. 324 * NOTE: this is not the same as the usable space in the ring. To query that 325 * use ``rte_ring_get_capacity()``. 326 */ 327 static inline unsigned int 328 rte_event_ring_get_size(const struct rte_event_ring *r) 329 { 330 return rte_ring_get_size(&r->r); 331 } 332 333 /** 334 * Return the number of elements which can be stored in the event ring. 335 * 336 * @param r 337 * A pointer to the ring structure. 338 * @return 339 * The usable size of the ring. 340 */ 341 static inline unsigned int 342 rte_event_ring_get_capacity(const struct rte_event_ring *r) 343 { 344 return rte_ring_get_capacity(&r->r); 345 } 346 347 #ifdef __cplusplus 348 } 349 #endif 350 351 #endif 352