1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright (c) 2010-2020 Intel Corporation
4 * Copyright (c) 2007-2009 Kip Macy [email protected]
5 * All rights reserved.
6 * Derived from FreeBSD's bufring.h
7 * Used as BSD-3 Licensed with permission from Kip Macy.
8 */
9
10 #ifndef _RTE_RING_H_
11 #define _RTE_RING_H_
12
13 /**
14 * @file
15 * RTE Ring
16 *
17 * The Ring Manager is a fixed-size queue, implemented as a table of
18 * pointers. Head and tail pointers are modified atomically, allowing
19 * concurrent access to it. It has the following features:
20 *
21 * - FIFO (First In First Out)
22 * - Maximum size is fixed; the pointers are stored in a table.
23 * - Lockless implementation.
24 * - Multi- or single-consumer dequeue.
25 * - Multi- or single-producer enqueue.
26 * - Bulk dequeue.
27 * - Bulk enqueue.
28 * - Ability to select different sync modes for producer/consumer.
29 * - Dequeue start/finish (depending on consumer sync modes).
30 * - Enqueue start/finish (depending on producer sync mode).
31 *
32 * Note: the ring implementation is not preemptible. Refer to Programmer's
33 * guide/Environment Abstraction Layer/Multiple pthread/Known Issues/rte_ring
34 * for more information.
35 *
36 */
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 #include <rte_ring_core.h>
43 #include <rte_ring_elem.h>
44
45 /**
46 * Calculate the memory size needed for a ring
47 *
48 * This function returns the number of bytes needed for a ring, given
49 * the number of elements in it. This value is the sum of the size of
50 * the structure rte_ring and the size of the memory needed by the
51 * objects pointers. The value is aligned to a cache line size.
52 *
53 * @param count
54 * The number of elements in the ring (must be a power of 2).
55 * @return
56 * - The memory size needed for the ring on success.
57 * - -EINVAL if count is not a power of 2.
58 */
59 ssize_t rte_ring_get_memsize(unsigned int count);
60
61 /**
62 * Initialize a ring structure.
63 *
64 * Initialize a ring structure in memory pointed by "r". The size of the
65 * memory area must be large enough to store the ring structure and the
66 * object table. It is advised to use rte_ring_get_memsize() to get the
67 * appropriate size.
68 *
69 * The ring size is set to *count*, which must be a power of two. Water
70 * marking is disabled by default. The real usable ring size is
71 * *count-1* instead of *count* to differentiate a free ring from an
72 * empty ring.
73 *
74 * The ring is not added in RTE_TAILQ_RING global list. Indeed, the
75 * memory given by the caller may not be shareable among dpdk
76 * processes.
77 *
78 * @param r
79 * The pointer to the ring structure followed by the objects table.
80 * @param name
81 * The name of the ring.
82 * @param count
83 * The number of elements in the ring (must be a power of 2).
84 * @param flags
85 * An OR of the following:
86 * - One of mutually exclusive flags that define producer behavior:
87 * - RING_F_SP_ENQ: If this flag is set, the default behavior when
88 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
89 * is "single-producer".
90 * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
91 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
92 * is "multi-producer RTS mode".
93 * - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when
94 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
95 * is "multi-producer HTS mode".
96 * If none of these flags is set, then default "multi-producer"
97 * behavior is selected.
98 * - One of mutually exclusive flags that define consumer behavior:
99 * - RING_F_SC_DEQ: If this flag is set, the default behavior when
100 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
101 * is "single-consumer". Otherwise, it is "multi-consumers".
102 * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
103 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
104 * is "multi-consumer RTS mode".
105 * - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when
106 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
107 * is "multi-consumer HTS mode".
108 * If none of these flags is set, then default "multi-consumer"
109 * behavior is selected.
110 * @return
111 * 0 on success, or a negative value on error.
112 */
113 int rte_ring_init(struct rte_ring *r, const char *name, unsigned int count,
114 unsigned int flags);
115
116 /**
117 * Create a new ring named *name* in memory.
118 *
119 * This function uses ``memzone_reserve()`` to allocate memory. Then it
120 * calls rte_ring_init() to initialize an empty ring.
121 *
122 * The new ring size is set to *count*, which must be a power of
123 * two. Water marking is disabled by default. The real usable ring size
124 * is *count-1* instead of *count* to differentiate a free ring from an
125 * empty ring.
126 *
127 * The ring is added in RTE_TAILQ_RING list.
128 *
129 * @param name
130 * The name of the ring.
131 * @param count
132 * The size of the ring (must be a power of 2).
133 * @param socket_id
134 * The *socket_id* argument is the socket identifier in case of
135 * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
136 * constraint for the reserved zone.
137 * @param flags
138 * An OR of the following:
139 * - One of mutually exclusive flags that define producer behavior:
140 * - RING_F_SP_ENQ: If this flag is set, the default behavior when
141 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
142 * is "single-producer".
143 * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
144 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
145 * is "multi-producer RTS mode".
146 * - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when
147 * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
148 * is "multi-producer HTS mode".
149 * If none of these flags is set, then default "multi-producer"
150 * behavior is selected.
151 * - One of mutually exclusive flags that define consumer behavior:
152 * - RING_F_SC_DEQ: If this flag is set, the default behavior when
153 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
154 * is "single-consumer". Otherwise, it is "multi-consumers".
155 * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
156 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
157 * is "multi-consumer RTS mode".
158 * - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when
159 * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
160 * is "multi-consumer HTS mode".
161 * If none of these flags is set, then default "multi-consumer"
162 * behavior is selected.
163 * @return
164 * On success, the pointer to the new allocated ring. NULL on error with
165 * rte_errno set appropriately. Possible errno values include:
166 * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
167 * - E_RTE_SECONDARY - function was called from a secondary process instance
168 * - EINVAL - count provided is not a power of 2
169 * - ENOSPC - the maximum number of memzones has already been allocated
170 * - EEXIST - a memzone with the same name already exists
171 * - ENOMEM - no appropriate memory area found in which to create memzone
172 */
173 struct rte_ring *rte_ring_create(const char *name, unsigned int count,
174 int socket_id, unsigned int flags);
175
176 /**
177 * De-allocate all memory used by the ring.
178 *
179 * @param r
180 * Ring to free
181 */
182 void rte_ring_free(struct rte_ring *r);
183
184 /**
185 * Dump the status of the ring to a file.
186 *
187 * @param f
188 * A pointer to a file for output
189 * @param r
190 * A pointer to the ring structure.
191 */
192 void rte_ring_dump(FILE *f, const struct rte_ring *r);
193
194 /**
195 * Enqueue several objects on the ring (multi-producers safe).
196 *
197 * This function uses a "compare and set" instruction to move the
198 * producer index atomically.
199 *
200 * @param r
201 * A pointer to the ring structure.
202 * @param obj_table
203 * A pointer to a table of void * pointers (objects).
204 * @param n
205 * The number of objects to add in the ring from the obj_table.
206 * @param free_space
207 * if non-NULL, returns the amount of space in the ring after the
208 * enqueue operation has finished.
209 * @return
210 * The number of objects enqueued, either 0 or n
211 */
212 static __rte_always_inline unsigned int
rte_ring_mp_enqueue_bulk(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)213 rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
214 unsigned int n, unsigned int *free_space)
215 {
216 return rte_ring_mp_enqueue_bulk_elem(r, obj_table, sizeof(void *),
217 n, free_space);
218 }
219
220 /**
221 * Enqueue several objects on a ring (NOT multi-producers safe).
222 *
223 * @param r
224 * A pointer to the ring structure.
225 * @param obj_table
226 * A pointer to a table of void * pointers (objects).
227 * @param n
228 * The number of objects to add in the ring from the obj_table.
229 * @param free_space
230 * if non-NULL, returns the amount of space in the ring after the
231 * enqueue operation has finished.
232 * @return
233 * The number of objects enqueued, either 0 or n
234 */
235 static __rte_always_inline unsigned int
rte_ring_sp_enqueue_bulk(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)236 rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
237 unsigned int n, unsigned int *free_space)
238 {
239 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, sizeof(void *),
240 n, free_space);
241 }
242
243 /**
244 * Enqueue several objects on a ring.
245 *
246 * This function calls the multi-producer or the single-producer
247 * version depending on the default behavior that was specified at
248 * ring creation time (see flags).
249 *
250 * @param r
251 * A pointer to the ring structure.
252 * @param obj_table
253 * A pointer to a table of void * pointers (objects).
254 * @param n
255 * The number of objects to add in the ring from the obj_table.
256 * @param free_space
257 * if non-NULL, returns the amount of space in the ring after the
258 * enqueue operation has finished.
259 * @return
260 * The number of objects enqueued, either 0 or n
261 */
262 static __rte_always_inline unsigned int
rte_ring_enqueue_bulk(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)263 rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
264 unsigned int n, unsigned int *free_space)
265 {
266 return rte_ring_enqueue_bulk_elem(r, obj_table, sizeof(void *),
267 n, free_space);
268 }
269
270 /**
271 * Enqueue one object on a ring (multi-producers safe).
272 *
273 * This function uses a "compare and set" instruction to move the
274 * producer index atomically.
275 *
276 * @param r
277 * A pointer to the ring structure.
278 * @param obj
279 * A pointer to the object to be added.
280 * @return
281 * - 0: Success; objects enqueued.
282 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
283 */
284 static __rte_always_inline int
rte_ring_mp_enqueue(struct rte_ring * r,void * obj)285 rte_ring_mp_enqueue(struct rte_ring *r, void *obj)
286 {
287 return rte_ring_mp_enqueue_elem(r, &obj, sizeof(void *));
288 }
289
290 /**
291 * Enqueue one object on a ring (NOT multi-producers safe).
292 *
293 * @param r
294 * A pointer to the ring structure.
295 * @param obj
296 * A pointer to the object to be added.
297 * @return
298 * - 0: Success; objects enqueued.
299 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
300 */
301 static __rte_always_inline int
rte_ring_sp_enqueue(struct rte_ring * r,void * obj)302 rte_ring_sp_enqueue(struct rte_ring *r, void *obj)
303 {
304 return rte_ring_sp_enqueue_elem(r, &obj, sizeof(void *));
305 }
306
307 /**
308 * Enqueue one object on a ring.
309 *
310 * This function calls the multi-producer or the single-producer
311 * version, depending on the default behaviour that was specified at
312 * ring creation time (see flags).
313 *
314 * @param r
315 * A pointer to the ring structure.
316 * @param obj
317 * A pointer to the object to be added.
318 * @return
319 * - 0: Success; objects enqueued.
320 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
321 */
322 static __rte_always_inline int
rte_ring_enqueue(struct rte_ring * r,void * obj)323 rte_ring_enqueue(struct rte_ring *r, void *obj)
324 {
325 return rte_ring_enqueue_elem(r, &obj, sizeof(void *));
326 }
327
328 /**
329 * Dequeue several objects from a ring (multi-consumers safe).
330 *
331 * This function uses a "compare and set" instruction to move the
332 * consumer index atomically.
333 *
334 * @param r
335 * A pointer to the ring structure.
336 * @param obj_table
337 * A pointer to a table of void * pointers (objects) that will be filled.
338 * @param n
339 * The number of objects to dequeue from the ring to the obj_table.
340 * @param available
341 * If non-NULL, returns the number of remaining ring entries after the
342 * dequeue has finished.
343 * @return
344 * The number of objects dequeued, either 0 or n
345 */
346 static __rte_always_inline unsigned int
rte_ring_mc_dequeue_bulk(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)347 rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
348 unsigned int n, unsigned int *available)
349 {
350 return rte_ring_mc_dequeue_bulk_elem(r, obj_table, sizeof(void *),
351 n, available);
352 }
353
354 /**
355 * Dequeue several objects from a ring (NOT multi-consumers safe).
356 *
357 * @param r
358 * A pointer to the ring structure.
359 * @param obj_table
360 * A pointer to a table of void * pointers (objects) that will be filled.
361 * @param n
362 * The number of objects to dequeue from the ring to the obj_table,
363 * must be strictly positive.
364 * @param available
365 * If non-NULL, returns the number of remaining ring entries after the
366 * dequeue has finished.
367 * @return
368 * The number of objects dequeued, either 0 or n
369 */
370 static __rte_always_inline unsigned int
rte_ring_sc_dequeue_bulk(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)371 rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
372 unsigned int n, unsigned int *available)
373 {
374 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, sizeof(void *),
375 n, available);
376 }
377
378 /**
379 * Dequeue several objects from a ring.
380 *
381 * This function calls the multi-consumers or the single-consumer
382 * version, depending on the default behaviour that was specified at
383 * ring creation time (see flags).
384 *
385 * @param r
386 * A pointer to the ring structure.
387 * @param obj_table
388 * A pointer to a table of void * pointers (objects) that will be filled.
389 * @param n
390 * The number of objects to dequeue from the ring to the obj_table.
391 * @param available
392 * If non-NULL, returns the number of remaining ring entries after the
393 * dequeue has finished.
394 * @return
395 * The number of objects dequeued, either 0 or n
396 */
397 static __rte_always_inline unsigned int
rte_ring_dequeue_bulk(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)398 rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
399 unsigned int *available)
400 {
401 return rte_ring_dequeue_bulk_elem(r, obj_table, sizeof(void *),
402 n, available);
403 }
404
405 /**
406 * Dequeue one object from a ring (multi-consumers safe).
407 *
408 * This function uses a "compare and set" instruction to move the
409 * consumer index atomically.
410 *
411 * @param r
412 * A pointer to the ring structure.
413 * @param obj_p
414 * A pointer to a void * pointer (object) that will be filled.
415 * @return
416 * - 0: Success; objects dequeued.
417 * - -ENOENT: Not enough entries in the ring to dequeue; no object is
418 * dequeued.
419 */
420 static __rte_always_inline int
rte_ring_mc_dequeue(struct rte_ring * r,void ** obj_p)421 rte_ring_mc_dequeue(struct rte_ring *r, void **obj_p)
422 {
423 return rte_ring_mc_dequeue_elem(r, obj_p, sizeof(void *));
424 }
425
426 /**
427 * Dequeue one object from a ring (NOT multi-consumers safe).
428 *
429 * @param r
430 * A pointer to the ring structure.
431 * @param obj_p
432 * A pointer to a void * pointer (object) that will be filled.
433 * @return
434 * - 0: Success; objects dequeued.
435 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
436 * dequeued.
437 */
438 static __rte_always_inline int
rte_ring_sc_dequeue(struct rte_ring * r,void ** obj_p)439 rte_ring_sc_dequeue(struct rte_ring *r, void **obj_p)
440 {
441 return rte_ring_sc_dequeue_elem(r, obj_p, sizeof(void *));
442 }
443
444 /**
445 * Dequeue one object from a ring.
446 *
447 * This function calls the multi-consumers or the single-consumer
448 * version depending on the default behaviour that was specified at
449 * ring creation time (see flags).
450 *
451 * @param r
452 * A pointer to the ring structure.
453 * @param obj_p
454 * A pointer to a void * pointer (object) that will be filled.
455 * @return
456 * - 0: Success, objects dequeued.
457 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
458 * dequeued.
459 */
460 static __rte_always_inline int
rte_ring_dequeue(struct rte_ring * r,void ** obj_p)461 rte_ring_dequeue(struct rte_ring *r, void **obj_p)
462 {
463 return rte_ring_dequeue_elem(r, obj_p, sizeof(void *));
464 }
465
466 /**
467 * Flush a ring.
468 *
469 * This function flush all the elements in a ring
470 *
471 * @warning
472 * Make sure the ring is not in use while calling this function.
473 *
474 * @param r
475 * A pointer to the ring structure.
476 */
477 void
478 rte_ring_reset(struct rte_ring *r);
479
480 /**
481 * Return the number of entries in a ring.
482 *
483 * @param r
484 * A pointer to the ring structure.
485 * @return
486 * The number of entries in the ring.
487 */
488 static inline unsigned int
rte_ring_count(const struct rte_ring * r)489 rte_ring_count(const struct rte_ring *r)
490 {
491 uint32_t prod_tail = r->prod.tail;
492 uint32_t cons_tail = r->cons.tail;
493 uint32_t count = (prod_tail - cons_tail) & r->mask;
494 return (count > r->capacity) ? r->capacity : count;
495 }
496
497 /**
498 * Return the number of free entries in a ring.
499 *
500 * @param r
501 * A pointer to the ring structure.
502 * @return
503 * The number of free entries in the ring.
504 */
505 static inline unsigned int
rte_ring_free_count(const struct rte_ring * r)506 rte_ring_free_count(const struct rte_ring *r)
507 {
508 return r->capacity - rte_ring_count(r);
509 }
510
511 /**
512 * Test if a ring is full.
513 *
514 * @param r
515 * A pointer to the ring structure.
516 * @return
517 * - 1: The ring is full.
518 * - 0: The ring is not full.
519 */
520 static inline int
rte_ring_full(const struct rte_ring * r)521 rte_ring_full(const struct rte_ring *r)
522 {
523 return rte_ring_free_count(r) == 0;
524 }
525
526 /**
527 * Test if a ring is empty.
528 *
529 * @param r
530 * A pointer to the ring structure.
531 * @return
532 * - 1: The ring is empty.
533 * - 0: The ring is not empty.
534 */
535 static inline int
rte_ring_empty(const struct rte_ring * r)536 rte_ring_empty(const struct rte_ring *r)
537 {
538 uint32_t prod_tail = r->prod.tail;
539 uint32_t cons_tail = r->cons.tail;
540 return cons_tail == prod_tail;
541 }
542
543 /**
544 * Return the size of the ring.
545 *
546 * @param r
547 * A pointer to the ring structure.
548 * @return
549 * The size of the data store used by the ring.
550 * NOTE: this is not the same as the usable space in the ring. To query that
551 * use ``rte_ring_get_capacity()``.
552 */
553 static inline unsigned int
rte_ring_get_size(const struct rte_ring * r)554 rte_ring_get_size(const struct rte_ring *r)
555 {
556 return r->size;
557 }
558
559 /**
560 * Return the number of elements which can be stored in the ring.
561 *
562 * @param r
563 * A pointer to the ring structure.
564 * @return
565 * The usable size of the ring.
566 */
567 static inline unsigned int
rte_ring_get_capacity(const struct rte_ring * r)568 rte_ring_get_capacity(const struct rte_ring *r)
569 {
570 return r->capacity;
571 }
572
573 /**
574 * Return sync type used by producer in the ring.
575 *
576 * @param r
577 * A pointer to the ring structure.
578 * @return
579 * Producer sync type value.
580 */
581 static inline enum rte_ring_sync_type
rte_ring_get_prod_sync_type(const struct rte_ring * r)582 rte_ring_get_prod_sync_type(const struct rte_ring *r)
583 {
584 return r->prod.sync_type;
585 }
586
587 /**
588 * Check is the ring for single producer.
589 *
590 * @param r
591 * A pointer to the ring structure.
592 * @return
593 * true if ring is SP, zero otherwise.
594 */
595 static inline int
rte_ring_is_prod_single(const struct rte_ring * r)596 rte_ring_is_prod_single(const struct rte_ring *r)
597 {
598 return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
599 }
600
601 /**
602 * Return sync type used by consumer in the ring.
603 *
604 * @param r
605 * A pointer to the ring structure.
606 * @return
607 * Consumer sync type value.
608 */
609 static inline enum rte_ring_sync_type
rte_ring_get_cons_sync_type(const struct rte_ring * r)610 rte_ring_get_cons_sync_type(const struct rte_ring *r)
611 {
612 return r->cons.sync_type;
613 }
614
615 /**
616 * Check is the ring for single consumer.
617 *
618 * @param r
619 * A pointer to the ring structure.
620 * @return
621 * true if ring is SC, zero otherwise.
622 */
623 static inline int
rte_ring_is_cons_single(const struct rte_ring * r)624 rte_ring_is_cons_single(const struct rte_ring *r)
625 {
626 return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
627 }
628
629 /**
630 * Dump the status of all rings on the console
631 *
632 * @param f
633 * A pointer to a file for output
634 */
635 void rte_ring_list_dump(FILE *f);
636
637 /**
638 * Search a ring from its name
639 *
640 * @param name
641 * The name of the ring.
642 * @return
643 * The pointer to the ring matching the name, or NULL if not found,
644 * with rte_errno set appropriately. Possible rte_errno values include:
645 * - ENOENT - required entry not available to return.
646 */
647 struct rte_ring *rte_ring_lookup(const char *name);
648
649 /**
650 * Enqueue several objects on the ring (multi-producers safe).
651 *
652 * This function uses a "compare and set" instruction to move the
653 * producer index atomically.
654 *
655 * @param r
656 * A pointer to the ring structure.
657 * @param obj_table
658 * A pointer to a table of void * pointers (objects).
659 * @param n
660 * The number of objects to add in the ring from the obj_table.
661 * @param free_space
662 * if non-NULL, returns the amount of space in the ring after the
663 * enqueue operation has finished.
664 * @return
665 * - n: Actual number of objects enqueued.
666 */
667 static __rte_always_inline unsigned int
rte_ring_mp_enqueue_burst(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)668 rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
669 unsigned int n, unsigned int *free_space)
670 {
671 return rte_ring_mp_enqueue_burst_elem(r, obj_table, sizeof(void *),
672 n, free_space);
673 }
674
675 /**
676 * Enqueue several objects on a ring (NOT multi-producers safe).
677 *
678 * @param r
679 * A pointer to the ring structure.
680 * @param obj_table
681 * A pointer to a table of void * pointers (objects).
682 * @param n
683 * The number of objects to add in the ring from the obj_table.
684 * @param free_space
685 * if non-NULL, returns the amount of space in the ring after the
686 * enqueue operation has finished.
687 * @return
688 * - n: Actual number of objects enqueued.
689 */
690 static __rte_always_inline unsigned int
rte_ring_sp_enqueue_burst(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)691 rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
692 unsigned int n, unsigned int *free_space)
693 {
694 return rte_ring_sp_enqueue_burst_elem(r, obj_table, sizeof(void *),
695 n, free_space);
696 }
697
698 /**
699 * Enqueue several objects on a ring.
700 *
701 * This function calls the multi-producer or the single-producer
702 * version depending on the default behavior that was specified at
703 * ring creation time (see flags).
704 *
705 * @param r
706 * A pointer to the ring structure.
707 * @param obj_table
708 * A pointer to a table of void * pointers (objects).
709 * @param n
710 * The number of objects to add in the ring from the obj_table.
711 * @param free_space
712 * if non-NULL, returns the amount of space in the ring after the
713 * enqueue operation has finished.
714 * @return
715 * - n: Actual number of objects enqueued.
716 */
717 static __rte_always_inline unsigned int
rte_ring_enqueue_burst(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)718 rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
719 unsigned int n, unsigned int *free_space)
720 {
721 return rte_ring_enqueue_burst_elem(r, obj_table, sizeof(void *),
722 n, free_space);
723 }
724
725 /**
726 * Dequeue several objects from a ring (multi-consumers safe). When the request
727 * objects are more than the available objects, only dequeue the actual number
728 * of objects
729 *
730 * This function uses a "compare and set" instruction to move the
731 * consumer index atomically.
732 *
733 * @param r
734 * A pointer to the ring structure.
735 * @param obj_table
736 * A pointer to a table of void * pointers (objects) that will be filled.
737 * @param n
738 * The number of objects to dequeue from the ring to the obj_table.
739 * @param available
740 * If non-NULL, returns the number of remaining ring entries after the
741 * dequeue has finished.
742 * @return
743 * - n: Actual number of objects dequeued, 0 if ring is empty
744 */
745 static __rte_always_inline unsigned int
rte_ring_mc_dequeue_burst(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)746 rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
747 unsigned int n, unsigned int *available)
748 {
749 return rte_ring_mc_dequeue_burst_elem(r, obj_table, sizeof(void *),
750 n, available);
751 }
752
753 /**
754 * Dequeue several objects from a ring (NOT multi-consumers safe).When the
755 * request objects are more than the available objects, only dequeue the
756 * actual number of objects
757 *
758 * @param r
759 * A pointer to the ring structure.
760 * @param obj_table
761 * A pointer to a table of void * pointers (objects) that will be filled.
762 * @param n
763 * The number of objects to dequeue from the ring to the obj_table.
764 * @param available
765 * If non-NULL, returns the number of remaining ring entries after the
766 * dequeue has finished.
767 * @return
768 * - n: Actual number of objects dequeued, 0 if ring is empty
769 */
770 static __rte_always_inline unsigned int
rte_ring_sc_dequeue_burst(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)771 rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
772 unsigned int n, unsigned int *available)
773 {
774 return rte_ring_sc_dequeue_burst_elem(r, obj_table, sizeof(void *),
775 n, available);
776 }
777
778 /**
779 * Dequeue multiple objects from a ring up to a maximum number.
780 *
781 * This function calls the multi-consumers or the single-consumer
782 * version, depending on the default behaviour that was specified at
783 * ring creation time (see flags).
784 *
785 * @param r
786 * A pointer to the ring structure.
787 * @param obj_table
788 * A pointer to a table of void * pointers (objects) that will be filled.
789 * @param n
790 * The number of objects to dequeue from the ring to the obj_table.
791 * @param available
792 * If non-NULL, returns the number of remaining ring entries after the
793 * dequeue has finished.
794 * @return
795 * - Number of objects dequeued
796 */
797 static __rte_always_inline unsigned int
rte_ring_dequeue_burst(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)798 rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
799 unsigned int n, unsigned int *available)
800 {
801 return rte_ring_dequeue_burst_elem(r, obj_table, sizeof(void *),
802 n, available);
803 }
804
805 #ifdef __cplusplus
806 }
807 #endif
808
809 #endif /* _RTE_RING_H_ */
810