net/virtio: fix incorrect cast of void *
[dpdk.git] / ring / rte_ring_elem.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2019 Arm Limited
4  * Copyright (c) 2010-2017 Intel Corporation
5  * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6  * All rights reserved.
7  * Derived from FreeBSD's bufring.h
8  * Used as BSD-3 Licensed with permission from Kip Macy.
9  */
10
11 #ifndef _RTE_RING_ELEM_H_
12 #define _RTE_RING_ELEM_H_
13
14 /**
15  * @file
16  * RTE Ring with user defined element size
17  */
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 #include <rte_ring_core.h>
24 #include <rte_ring_elem_pvt.h>
25
26 /**
27  * Calculate the memory size needed for a ring with given element size
28  *
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
33  * line size.
34  *
35  * @param esize
36  *   The size of ring element, in bytes. It must be a multiple of 4.
37  * @param count
38  *   The number of elements in the ring (must be a power of 2).
39  * @return
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
42  *               power of 2.
43  */
44 ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
45
46 /**
47  * Create a new ring named *name* that stores elements with given size.
48  *
49  * This function uses ``memzone_reserve()`` to allocate memory. Then it
50  * calls rte_ring_init() to initialize an empty ring.
51  *
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
55  * empty ring.
56  *
57  * The ring is added in RTE_TAILQ_RING list.
58  *
59  * @param name
60  *   The name of the ring.
61  * @param esize
62  *   The size of ring element, in bytes. It must be a multiple of 4.
63  * @param count
64  *   The number of elements in the ring (must be a power of 2).
65  * @param socket_id
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.
69  * @param flags
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.
95  * @return
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
101  *               power of 2.
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
105  */
106 struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize,
107                         unsigned int count, int socket_id, unsigned int flags);
108
109 /**
110  * Enqueue several objects on the ring (multi-producers safe).
111  *
112  * This function uses a "compare and set" instruction to move the
113  * producer index atomically.
114  *
115  * @param r
116  *   A pointer to the ring structure.
117  * @param obj_table
118  *   A pointer to a table of objects.
119  * @param esize
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.
123  * @param n
124  *   The number of objects to add in the ring from the obj_table.
125  * @param free_space
126  *   if non-NULL, returns the amount of space in the ring after the
127  *   enqueue operation has finished.
128  * @return
129  *   The number of objects enqueued, either 0 or n
130  */
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)
134 {
135         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
136                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
137 }
138
139 /**
140  * Enqueue several objects on a ring
141  *
142  * @warning This API is NOT multi-producers safe
143  *
144  * @param r
145  *   A pointer to the ring structure.
146  * @param obj_table
147  *   A pointer to a table of objects.
148  * @param esize
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.
152  * @param n
153  *   The number of objects to add in the ring from the obj_table.
154  * @param free_space
155  *   if non-NULL, returns the amount of space in the ring after the
156  *   enqueue operation has finished.
157  * @return
158  *   The number of objects enqueued, either 0 or n
159  */
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)
163 {
164         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
165                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
166 }
167
168 #ifdef ALLOW_EXPERIMENTAL_API
169 #include <rte_ring_hts.h>
170 #include <rte_ring_rts.h>
171 #endif
172
173 /**
174  * Enqueue several objects on a ring.
175  *
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).
179  *
180  * @param r
181  *   A pointer to the ring structure.
182  * @param obj_table
183  *   A pointer to a table of objects.
184  * @param esize
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.
188  * @param n
189  *   The number of objects to add in the ring from the obj_table.
190  * @param free_space
191  *   if non-NULL, returns the amount of space in the ring after the
192  *   enqueue operation has finished.
193  * @return
194  *   The number of objects enqueued, either 0 or n
195  */
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)
199 {
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,
203                         free_space);
204         case RTE_RING_SYNC_ST:
205                 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
206                         free_space);
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,
210                         free_space);
211         case RTE_RING_SYNC_MT_HTS:
212                 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
213                         free_space);
214 #endif
215         }
216
217         /* valid ring should never reach this point */
218         RTE_ASSERT(0);
219         if (free_space != NULL)
220                 *free_space = 0;
221         return 0;
222 }
223
224 /**
225  * Enqueue one object on a ring (multi-producers safe).
226  *
227  * This function uses a "compare and set" instruction to move the
228  * producer index atomically.
229  *
230  * @param r
231  *   A pointer to the ring structure.
232  * @param obj
233  *   A pointer to the object to be added.
234  * @param esize
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.
238  * @return
239  *   - 0: Success; objects enqueued.
240  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
241  */
242 static __rte_always_inline int
243 rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
244 {
245         return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
246                                                                 -ENOBUFS;
247 }
248
249 /**
250  * Enqueue one object on a ring
251  *
252  * @warning This API is NOT multi-producers safe
253  *
254  * @param r
255  *   A pointer to the ring structure.
256  * @param obj
257  *   A pointer to the object to be added.
258  * @param esize
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.
262  * @return
263  *   - 0: Success; objects enqueued.
264  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
265  */
266 static __rte_always_inline int
267 rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
268 {
269         return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
270                                                                 -ENOBUFS;
271 }
272
273 /**
274  * Enqueue one object on a ring.
275  *
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).
279  *
280  * @param r
281  *   A pointer to the ring structure.
282  * @param obj
283  *   A pointer to the object to be added.
284  * @param esize
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.
288  * @return
289  *   - 0: Success; objects enqueued.
290  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
291  */
292 static __rte_always_inline int
293 rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
294 {
295         return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
296                                                                 -ENOBUFS;
297 }
298
299 /**
300  * Dequeue several objects from a ring (multi-consumers safe).
301  *
302  * This function uses a "compare and set" instruction to move the
303  * consumer index atomically.
304  *
305  * @param r
306  *   A pointer to the ring structure.
307  * @param obj_table
308  *   A pointer to a table of objects that will be filled.
309  * @param esize
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.
313  * @param n
314  *   The number of objects to dequeue from the ring to the obj_table.
315  * @param available
316  *   If non-NULL, returns the number of remaining ring entries after the
317  *   dequeue has finished.
318  * @return
319  *   The number of objects dequeued, either 0 or n
320  */
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)
324 {
325         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
326                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
327 }
328
329 /**
330  * Dequeue several objects from a ring (NOT multi-consumers safe).
331  *
332  * @param r
333  *   A pointer to the ring structure.
334  * @param obj_table
335  *   A pointer to a table of objects that will be filled.
336  * @param esize
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.
340  * @param n
341  *   The number of objects to dequeue from the ring to the obj_table,
342  *   must be strictly positive.
343  * @param available
344  *   If non-NULL, returns the number of remaining ring entries after the
345  *   dequeue has finished.
346  * @return
347  *   The number of objects dequeued, either 0 or n
348  */
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)
352 {
353         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
354                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
355 }
356
357 /**
358  * Dequeue several objects from a ring.
359  *
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).
363  *
364  * @param r
365  *   A pointer to the ring structure.
366  * @param obj_table
367  *   A pointer to a table of objects that will be filled.
368  * @param esize
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.
372  * @param n
373  *   The number of objects to dequeue from the ring to the obj_table.
374  * @param available
375  *   If non-NULL, returns the number of remaining ring entries after the
376  *   dequeue has finished.
377  * @return
378  *   The number of objects dequeued, either 0 or n
379  */
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)
383 {
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,
387                         available);
388         case RTE_RING_SYNC_ST:
389                 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
390                         available);
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,
394                         n, available);
395         case RTE_RING_SYNC_MT_HTS:
396                 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
397                         n, available);
398 #endif
399         }
400
401         /* valid ring should never reach this point */
402         RTE_ASSERT(0);
403         if (available != NULL)
404                 *available = 0;
405         return 0;
406 }
407
408 /**
409  * Dequeue one object from a ring (multi-consumers safe).
410  *
411  * This function uses a "compare and set" instruction to move the
412  * consumer index atomically.
413  *
414  * @param r
415  *   A pointer to the ring structure.
416  * @param obj_p
417  *   A pointer to the object that will be filled.
418  * @param esize
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.
422  * @return
423  *   - 0: Success; objects dequeued.
424  *   - -ENOENT: Not enough entries in the ring to dequeue; no object is
425  *     dequeued.
426  */
427 static __rte_always_inline int
428 rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
429                                 unsigned int esize)
430 {
431         return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL)  ? 0 :
432                                                                 -ENOENT;
433 }
434
435 /**
436  * Dequeue one object from a ring (NOT multi-consumers safe).
437  *
438  * @param r
439  *   A pointer to the ring structure.
440  * @param obj_p
441  *   A pointer to the object that will be filled.
442  * @param esize
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.
446  * @return
447  *   - 0: Success; objects dequeued.
448  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
449  *     dequeued.
450  */
451 static __rte_always_inline int
452 rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
453                                 unsigned int esize)
454 {
455         return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
456                                                                 -ENOENT;
457 }
458
459 /**
460  * Dequeue one object from a ring.
461  *
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).
465  *
466  * @param r
467  *   A pointer to the ring structure.
468  * @param obj_p
469  *   A pointer to the object that will be filled.
470  * @param esize
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.
474  * @return
475  *   - 0: Success, objects dequeued.
476  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
477  *     dequeued.
478  */
479 static __rte_always_inline int
480 rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
481 {
482         return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
483                                                                 -ENOENT;
484 }
485
486 /**
487  * Enqueue several objects on the ring (multi-producers safe).
488  *
489  * This function uses a "compare and set" instruction to move the
490  * producer index atomically.
491  *
492  * @param r
493  *   A pointer to the ring structure.
494  * @param obj_table
495  *   A pointer to a table of objects.
496  * @param esize
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.
500  * @param n
501  *   The number of objects to add in the ring from the obj_table.
502  * @param free_space
503  *   if non-NULL, returns the amount of space in the ring after the
504  *   enqueue operation has finished.
505  * @return
506  *   - n: Actual number of objects enqueued.
507  */
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)
511 {
512         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
513                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
514 }
515
516 /**
517  * Enqueue several objects on a ring
518  *
519  * @warning This API is NOT multi-producers safe
520  *
521  * @param r
522  *   A pointer to the ring structure.
523  * @param obj_table
524  *   A pointer to a table of objects.
525  * @param esize
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.
529  * @param n
530  *   The number of objects to add in the ring from the obj_table.
531  * @param free_space
532  *   if non-NULL, returns the amount of space in the ring after the
533  *   enqueue operation has finished.
534  * @return
535  *   - n: Actual number of objects enqueued.
536  */
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)
540 {
541         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
542                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
543 }
544
545 /**
546  * Enqueue several objects on a ring.
547  *
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).
551  *
552  * @param r
553  *   A pointer to the ring structure.
554  * @param obj_table
555  *   A pointer to a table of objects.
556  * @param esize
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.
560  * @param n
561  *   The number of objects to add in the ring from the obj_table.
562  * @param free_space
563  *   if non-NULL, returns the amount of space in the ring after the
564  *   enqueue operation has finished.
565  * @return
566  *   - n: Actual number of objects enqueued.
567  */
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)
571 {
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,
575                         free_space);
576         case RTE_RING_SYNC_ST:
577                 return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
578                         free_space);
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,
582                         n, free_space);
583         case RTE_RING_SYNC_MT_HTS:
584                 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
585                         n, free_space);
586 #endif
587         }
588
589         /* valid ring should never reach this point */
590         RTE_ASSERT(0);
591         if (free_space != NULL)
592                 *free_space = 0;
593         return 0;
594 }
595
596 /**
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
599  * of objects
600  *
601  * This function uses a "compare and set" instruction to move the
602  * consumer index atomically.
603  *
604  * @param r
605  *   A pointer to the ring structure.
606  * @param obj_table
607  *   A pointer to a table of objects that will be filled.
608  * @param esize
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.
612  * @param n
613  *   The number of objects to dequeue from the ring to the obj_table.
614  * @param available
615  *   If non-NULL, returns the number of remaining ring entries after the
616  *   dequeue has finished.
617  * @return
618  *   - n: Actual number of objects dequeued, 0 if ring is empty
619  */
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)
623 {
624         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
625                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
626 }
627
628 /**
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
632  *
633  * @param r
634  *   A pointer to the ring structure.
635  * @param obj_table
636  *   A pointer to a table of objects that will be filled.
637  * @param esize
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.
641  * @param n
642  *   The number of objects to dequeue from the ring to the obj_table.
643  * @param available
644  *   If non-NULL, returns the number of remaining ring entries after the
645  *   dequeue has finished.
646  * @return
647  *   - n: Actual number of objects dequeued, 0 if ring is empty
648  */
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)
652 {
653         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
654                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
655 }
656
657 /**
658  * Dequeue multiple objects from a ring up to a maximum number.
659  *
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).
663  *
664  * @param r
665  *   A pointer to the ring structure.
666  * @param obj_table
667  *   A pointer to a table of objects that will be filled.
668  * @param esize
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.
672  * @param n
673  *   The number of objects to dequeue from the ring to the obj_table.
674  * @param available
675  *   If non-NULL, returns the number of remaining ring entries after the
676  *   dequeue has finished.
677  * @return
678  *   - Number of objects dequeued
679  */
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)
683 {
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,
687                         available);
688         case RTE_RING_SYNC_ST:
689                 return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
690                         available);
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,
694                         n, available);
695         case RTE_RING_SYNC_MT_HTS:
696                 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
697                         n, available);
698 #endif
699         }
700
701         /* valid ring should never reach this point */
702         RTE_ASSERT(0);
703         if (available != NULL)
704                 *available = 0;
705         return 0;
706 }
707
708 #ifdef ALLOW_EXPERIMENTAL_API
709 #include <rte_ring_peek.h>
710 #include <rte_ring_peek_zc.h>
711 #endif
712
713 #include <rte_ring.h>
714
715 #ifdef __cplusplus
716 }
717 #endif
718
719 #endif /* _RTE_RING_ELEM_H_ */