1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2019 Arm Limited
4 * Copyright (c) 2010-2017 Intel Corporation
5 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
7 * Derived from FreeBSD's bufring.h
8 * Used as BSD-3 Licensed with permission from Kip Macy.
11 #ifndef _RTE_RING_ELEM_H_
12 #define _RTE_RING_ELEM_H_
16 * RTE Ring with user defined element size
23 #include <rte_ring_core.h>
24 #include <rte_ring_elem_pvt.h>
27 * Calculate the memory size needed for a ring with given element size
29 * This function returns the number of bytes needed for a ring, given
30 * the number of elements in it and the size of the element. This value
31 * is the sum of the size of the structure rte_ring and the size of the
32 * memory needed for storing the elements. The value is aligned to a cache
36 * The size of ring element, in bytes. It must be a multiple of 4.
38 * The number of elements in the ring (must be a power of 2).
40 * - The memory size needed for the ring on success.
41 * - -EINVAL - esize is not a multiple of 4 or count provided is not a
44 ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
47 * Create a new ring named *name* that stores elements with given size.
49 * This function uses ``memzone_reserve()`` to allocate memory. Then it
50 * calls rte_ring_init() to initialize an empty ring.
52 * The new ring size is set to *count*, which must be a power of
53 * two. Water marking is disabled by default. The real usable ring size
54 * is *count-1* instead of *count* to differentiate a free ring from an
57 * The ring is added in RTE_TAILQ_RING list.
60 * The name of the ring.
62 * The size of ring element, in bytes. It must be a multiple of 4.
64 * The number of elements in the ring (must be a power of 2).
66 * The *socket_id* argument is the socket identifier in case of
67 * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
68 * constraint for the reserved zone.
70 * An OR of the following:
71 * - One of mutually exclusive flags that define producer behavior:
72 * - RING_F_SP_ENQ: If this flag is set, the default behavior when
73 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
74 * is "single-producer".
75 * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
76 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
77 * is "multi-producer RTS mode".
78 * - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when
79 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
80 * is "multi-producer HTS mode".
81 * If none of these flags is set, then default "multi-producer"
82 * behavior is selected.
83 * - One of mutually exclusive flags that define consumer behavior:
84 * - RING_F_SC_DEQ: If this flag is set, the default behavior when
85 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
86 * is "single-consumer". Otherwise, it is "multi-consumers".
87 * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
88 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
89 * is "multi-consumer RTS mode".
90 * - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when
91 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
92 * is "multi-consumer HTS mode".
93 * If none of these flags is set, then default "multi-consumer"
94 * behavior is selected.
96 * On success, the pointer to the new allocated ring. NULL on error with
97 * rte_errno set appropriately. Possible errno values include:
98 * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
99 * - E_RTE_SECONDARY - function was called from a secondary process instance
100 * - EINVAL - esize is not a multiple of 4 or count provided is not a
102 * - ENOSPC - the maximum number of memzones has already been allocated
103 * - EEXIST - a memzone with the same name already exists
104 * - ENOMEM - no appropriate memory area found in which to create memzone
106 struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize,
107 unsigned int count, int socket_id, unsigned int flags);
110 * Enqueue several objects on the ring (multi-producers safe).
112 * This function uses a "compare and set" instruction to move the
113 * producer index atomically.
116 * A pointer to the ring structure.
118 * A pointer to a table of objects.
120 * The size of ring element, in bytes. It must be a multiple of 4.
121 * This must be the same value used while creating the ring. Otherwise
122 * the results are undefined.
124 * The number of objects to add in the ring from the obj_table.
126 * if non-NULL, returns the amount of space in the ring after the
127 * enqueue operation has finished.
129 * The number of objects enqueued, either 0 or n
131 static __rte_always_inline unsigned int
132 rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
133 unsigned int esize, unsigned int n, unsigned int *free_space)
135 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
136 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
140 * Enqueue several objects on a ring
142 * @warning This API is NOT multi-producers safe
145 * A pointer to the ring structure.
147 * A pointer to a table of objects.
149 * The size of ring element, in bytes. It must be a multiple of 4.
150 * This must be the same value used while creating the ring. Otherwise
151 * the results are undefined.
153 * The number of objects to add in the ring from the obj_table.
155 * if non-NULL, returns the amount of space in the ring after the
156 * enqueue operation has finished.
158 * The number of objects enqueued, either 0 or n
160 static __rte_always_inline unsigned int
161 rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
162 unsigned int esize, unsigned int n, unsigned int *free_space)
164 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
165 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
168 #ifdef ALLOW_EXPERIMENTAL_API
169 #include <rte_ring_hts.h>
170 #include <rte_ring_rts.h>
174 * Enqueue several objects on a ring.
176 * This function calls the multi-producer or the single-producer
177 * version depending on the default behavior that was specified at
178 * ring creation time (see flags).
181 * A pointer to the ring structure.
183 * A pointer to a table of objects.
185 * The size of ring element, in bytes. It must be a multiple of 4.
186 * This must be the same value used while creating the ring. Otherwise
187 * the results are undefined.
189 * The number of objects to add in the ring from the obj_table.
191 * if non-NULL, returns the amount of space in the ring after the
192 * enqueue operation has finished.
194 * The number of objects enqueued, either 0 or n
196 static __rte_always_inline unsigned int
197 rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
198 unsigned int esize, unsigned int n, unsigned int *free_space)
200 switch (r->prod.sync_type) {
201 case RTE_RING_SYNC_MT:
202 return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
204 case RTE_RING_SYNC_ST:
205 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
207 #ifdef ALLOW_EXPERIMENTAL_API
208 case RTE_RING_SYNC_MT_RTS:
209 return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
211 case RTE_RING_SYNC_MT_HTS:
212 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
217 /* valid ring should never reach this point */
219 if (free_space != NULL)
225 * Enqueue one object on a ring (multi-producers safe).
227 * This function uses a "compare and set" instruction to move the
228 * producer index atomically.
231 * A pointer to the ring structure.
233 * A pointer to the object to be added.
235 * The size of ring element, in bytes. It must be a multiple of 4.
236 * This must be the same value used while creating the ring. Otherwise
237 * the results are undefined.
239 * - 0: Success; objects enqueued.
240 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
242 static __rte_always_inline int
243 rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
245 return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
250 * Enqueue one object on a ring
252 * @warning This API is NOT multi-producers safe
255 * A pointer to the ring structure.
257 * A pointer to the object to be added.
259 * The size of ring element, in bytes. It must be a multiple of 4.
260 * This must be the same value used while creating the ring. Otherwise
261 * the results are undefined.
263 * - 0: Success; objects enqueued.
264 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
266 static __rte_always_inline int
267 rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
269 return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
274 * Enqueue one object on a ring.
276 * This function calls the multi-producer or the single-producer
277 * version, depending on the default behaviour that was specified at
278 * ring creation time (see flags).
281 * A pointer to the ring structure.
283 * A pointer to the object to be added.
285 * The size of ring element, in bytes. It must be a multiple of 4.
286 * This must be the same value used while creating the ring. Otherwise
287 * the results are undefined.
289 * - 0: Success; objects enqueued.
290 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
292 static __rte_always_inline int
293 rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
295 return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
300 * Dequeue several objects from a ring (multi-consumers safe).
302 * This function uses a "compare and set" instruction to move the
303 * consumer index atomically.
306 * A pointer to the ring structure.
308 * A pointer to a table of objects that will be filled.
310 * The size of ring element, in bytes. It must be a multiple of 4.
311 * This must be the same value used while creating the ring. Otherwise
312 * the results are undefined.
314 * The number of objects to dequeue from the ring to the obj_table.
316 * If non-NULL, returns the number of remaining ring entries after the
317 * dequeue has finished.
319 * The number of objects dequeued, either 0 or n
321 static __rte_always_inline unsigned int
322 rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
323 unsigned int esize, unsigned int n, unsigned int *available)
325 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
326 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
330 * Dequeue several objects from a ring (NOT multi-consumers safe).
333 * A pointer to the ring structure.
335 * A pointer to a table of objects that will be filled.
337 * The size of ring element, in bytes. It must be a multiple of 4.
338 * This must be the same value used while creating the ring. Otherwise
339 * the results are undefined.
341 * The number of objects to dequeue from the ring to the obj_table,
342 * must be strictly positive.
344 * If non-NULL, returns the number of remaining ring entries after the
345 * dequeue has finished.
347 * The number of objects dequeued, either 0 or n
349 static __rte_always_inline unsigned int
350 rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
351 unsigned int esize, unsigned int n, unsigned int *available)
353 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
354 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
358 * Dequeue several objects from a ring.
360 * This function calls the multi-consumers or the single-consumer
361 * version, depending on the default behaviour that was specified at
362 * ring creation time (see flags).
365 * A pointer to the ring structure.
367 * A pointer to a table of objects that will be filled.
369 * The size of ring element, in bytes. It must be a multiple of 4.
370 * This must be the same value used while creating the ring. Otherwise
371 * the results are undefined.
373 * The number of objects to dequeue from the ring to the obj_table.
375 * If non-NULL, returns the number of remaining ring entries after the
376 * dequeue has finished.
378 * The number of objects dequeued, either 0 or n
380 static __rte_always_inline unsigned int
381 rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
382 unsigned int esize, unsigned int n, unsigned int *available)
384 switch (r->cons.sync_type) {
385 case RTE_RING_SYNC_MT:
386 return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
388 case RTE_RING_SYNC_ST:
389 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
391 #ifdef ALLOW_EXPERIMENTAL_API
392 case RTE_RING_SYNC_MT_RTS:
393 return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
395 case RTE_RING_SYNC_MT_HTS:
396 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
401 /* valid ring should never reach this point */
403 if (available != NULL)
409 * Dequeue one object from a ring (multi-consumers safe).
411 * This function uses a "compare and set" instruction to move the
412 * consumer index atomically.
415 * A pointer to the ring structure.
417 * A pointer to the object that will be filled.
419 * The size of ring element, in bytes. It must be a multiple of 4.
420 * This must be the same value used while creating the ring. Otherwise
421 * the results are undefined.
423 * - 0: Success; objects dequeued.
424 * - -ENOENT: Not enough entries in the ring to dequeue; no object is
427 static __rte_always_inline int
428 rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
431 return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
436 * Dequeue one object from a ring (NOT multi-consumers safe).
439 * A pointer to the ring structure.
441 * A pointer to the object that will be filled.
443 * The size of ring element, in bytes. It must be a multiple of 4.
444 * This must be the same value used while creating the ring. Otherwise
445 * the results are undefined.
447 * - 0: Success; objects dequeued.
448 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
451 static __rte_always_inline int
452 rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
455 return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
460 * Dequeue one object from a ring.
462 * This function calls the multi-consumers or the single-consumer
463 * version depending on the default behaviour that was specified at
464 * ring creation time (see flags).
467 * A pointer to the ring structure.
469 * A pointer to the object that will be filled.
471 * The size of ring element, in bytes. It must be a multiple of 4.
472 * This must be the same value used while creating the ring. Otherwise
473 * the results are undefined.
475 * - 0: Success, objects dequeued.
476 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
479 static __rte_always_inline int
480 rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
482 return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
487 * Enqueue several objects on the ring (multi-producers safe).
489 * This function uses a "compare and set" instruction to move the
490 * producer index atomically.
493 * A pointer to the ring structure.
495 * A pointer to a table of objects.
497 * The size of ring element, in bytes. It must be a multiple of 4.
498 * This must be the same value used while creating the ring. Otherwise
499 * the results are undefined.
501 * The number of objects to add in the ring from the obj_table.
503 * if non-NULL, returns the amount of space in the ring after the
504 * enqueue operation has finished.
506 * - n: Actual number of objects enqueued.
508 static __rte_always_inline unsigned int
509 rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
510 unsigned int esize, unsigned int n, unsigned int *free_space)
512 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
513 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
517 * Enqueue several objects on a ring
519 * @warning This API is NOT multi-producers safe
522 * A pointer to the ring structure.
524 * A pointer to a table of objects.
526 * The size of ring element, in bytes. It must be a multiple of 4.
527 * This must be the same value used while creating the ring. Otherwise
528 * the results are undefined.
530 * The number of objects to add in the ring from the obj_table.
532 * if non-NULL, returns the amount of space in the ring after the
533 * enqueue operation has finished.
535 * - n: Actual number of objects enqueued.
537 static __rte_always_inline unsigned int
538 rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
539 unsigned int esize, unsigned int n, unsigned int *free_space)
541 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
542 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
546 * Enqueue several objects on a ring.
548 * This function calls the multi-producer or the single-producer
549 * version depending on the default behavior that was specified at
550 * ring creation time (see flags).
553 * A pointer to the ring structure.
555 * A pointer to a table of objects.
557 * The size of ring element, in bytes. It must be a multiple of 4.
558 * This must be the same value used while creating the ring. Otherwise
559 * the results are undefined.
561 * The number of objects to add in the ring from the obj_table.
563 * if non-NULL, returns the amount of space in the ring after the
564 * enqueue operation has finished.
566 * - n: Actual number of objects enqueued.
568 static __rte_always_inline unsigned int
569 rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
570 unsigned int esize, unsigned int n, unsigned int *free_space)
572 switch (r->prod.sync_type) {
573 case RTE_RING_SYNC_MT:
574 return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
576 case RTE_RING_SYNC_ST:
577 return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
579 #ifdef ALLOW_EXPERIMENTAL_API
580 case RTE_RING_SYNC_MT_RTS:
581 return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
583 case RTE_RING_SYNC_MT_HTS:
584 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
589 /* valid ring should never reach this point */
591 if (free_space != NULL)
597 * Dequeue several objects from a ring (multi-consumers safe). When the request
598 * objects are more than the available objects, only dequeue the actual number
601 * This function uses a "compare and set" instruction to move the
602 * consumer index atomically.
605 * A pointer to the ring structure.
607 * A pointer to a table of objects that will be filled.
609 * The size of ring element, in bytes. It must be a multiple of 4.
610 * This must be the same value used while creating the ring. Otherwise
611 * the results are undefined.
613 * The number of objects to dequeue from the ring to the obj_table.
615 * If non-NULL, returns the number of remaining ring entries after the
616 * dequeue has finished.
618 * - n: Actual number of objects dequeued, 0 if ring is empty
620 static __rte_always_inline unsigned int
621 rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
622 unsigned int esize, unsigned int n, unsigned int *available)
624 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
625 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
629 * Dequeue several objects from a ring (NOT multi-consumers safe).When the
630 * request objects are more than the available objects, only dequeue the
631 * actual number of objects
634 * A pointer to the ring structure.
636 * A pointer to a table of objects that will be filled.
638 * The size of ring element, in bytes. It must be a multiple of 4.
639 * This must be the same value used while creating the ring. Otherwise
640 * the results are undefined.
642 * The number of objects to dequeue from the ring to the obj_table.
644 * If non-NULL, returns the number of remaining ring entries after the
645 * dequeue has finished.
647 * - n: Actual number of objects dequeued, 0 if ring is empty
649 static __rte_always_inline unsigned int
650 rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
651 unsigned int esize, unsigned int n, unsigned int *available)
653 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
654 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
658 * Dequeue multiple objects from a ring up to a maximum number.
660 * This function calls the multi-consumers or the single-consumer
661 * version, depending on the default behaviour that was specified at
662 * ring creation time (see flags).
665 * A pointer to the ring structure.
667 * A pointer to a table of objects that will be filled.
669 * The size of ring element, in bytes. It must be a multiple of 4.
670 * This must be the same value used while creating the ring. Otherwise
671 * the results are undefined.
673 * The number of objects to dequeue from the ring to the obj_table.
675 * If non-NULL, returns the number of remaining ring entries after the
676 * dequeue has finished.
678 * - Number of objects dequeued
680 static __rte_always_inline unsigned int
681 rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
682 unsigned int esize, unsigned int n, unsigned int *available)
684 switch (r->cons.sync_type) {
685 case RTE_RING_SYNC_MT:
686 return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
688 case RTE_RING_SYNC_ST:
689 return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
691 #ifdef ALLOW_EXPERIMENTAL_API
692 case RTE_RING_SYNC_MT_RTS:
693 return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
695 case RTE_RING_SYNC_MT_HTS:
696 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
701 /* valid ring should never reach this point */
703 if (available != NULL)
708 #ifdef ALLOW_EXPERIMENTAL_API
709 #include <rte_ring_peek.h>
710 #include <rte_ring_peek_zc.h>
713 #include <rte_ring.h>
719 #endif /* _RTE_RING_ELEM_H_ */