sched: move grinder configuration
[dpdk.git] / lib / 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 full 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 #include <rte_ring_hts.h>
169 #include <rte_ring_rts.h>
170
171 /**
172  * Enqueue several objects on a ring.
173  *
174  * This function calls the multi-producer or the single-producer
175  * version depending on the default behavior that was specified at
176  * ring creation time (see flags).
177  *
178  * @param r
179  *   A pointer to the ring structure.
180  * @param obj_table
181  *   A pointer to a table of objects.
182  * @param esize
183  *   The size of ring element, in bytes. It must be a multiple of 4.
184  *   This must be the same value used while creating the ring. Otherwise
185  *   the results are undefined.
186  * @param n
187  *   The number of objects to add in the ring from the obj_table.
188  * @param free_space
189  *   if non-NULL, returns the amount of space in the ring after the
190  *   enqueue operation has finished.
191  * @return
192  *   The number of objects enqueued, either 0 or n
193  */
194 static __rte_always_inline unsigned int
195 rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
196                 unsigned int esize, unsigned int n, unsigned int *free_space)
197 {
198         switch (r->prod.sync_type) {
199         case RTE_RING_SYNC_MT:
200                 return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
201                         free_space);
202         case RTE_RING_SYNC_ST:
203                 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
204                         free_space);
205         case RTE_RING_SYNC_MT_RTS:
206                 return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
207                         free_space);
208         case RTE_RING_SYNC_MT_HTS:
209                 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
210                         free_space);
211         }
212
213         /* valid ring should never reach this point */
214         RTE_ASSERT(0);
215         if (free_space != NULL)
216                 *free_space = 0;
217         return 0;
218 }
219
220 /**
221  * Enqueue one object on a ring (multi-producers safe).
222  *
223  * This function uses a "compare and set" instruction to move the
224  * producer index atomically.
225  *
226  * @param r
227  *   A pointer to the ring structure.
228  * @param obj
229  *   A pointer to the object to be added.
230  * @param esize
231  *   The size of ring element, in bytes. It must be a multiple of 4.
232  *   This must be the same value used while creating the ring. Otherwise
233  *   the results are undefined.
234  * @return
235  *   - 0: Success; objects enqueued.
236  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
237  */
238 static __rte_always_inline int
239 rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
240 {
241         return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
242                                                                 -ENOBUFS;
243 }
244
245 /**
246  * Enqueue one object on a ring
247  *
248  * @warning This API is NOT multi-producers safe
249  *
250  * @param r
251  *   A pointer to the ring structure.
252  * @param obj
253  *   A pointer to the object to be added.
254  * @param esize
255  *   The size of ring element, in bytes. It must be a multiple of 4.
256  *   This must be the same value used while creating the ring. Otherwise
257  *   the results are undefined.
258  * @return
259  *   - 0: Success; objects enqueued.
260  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
261  */
262 static __rte_always_inline int
263 rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
264 {
265         return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
266                                                                 -ENOBUFS;
267 }
268
269 /**
270  * Enqueue one object on a ring.
271  *
272  * This function calls the multi-producer or the single-producer
273  * version, depending on the default behaviour that was specified at
274  * ring creation time (see flags).
275  *
276  * @param r
277  *   A pointer to the ring structure.
278  * @param obj
279  *   A pointer to the object to be added.
280  * @param esize
281  *   The size of ring element, in bytes. It must be a multiple of 4.
282  *   This must be the same value used while creating the ring. Otherwise
283  *   the results are undefined.
284  * @return
285  *   - 0: Success; objects enqueued.
286  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
287  */
288 static __rte_always_inline int
289 rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
290 {
291         return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
292                                                                 -ENOBUFS;
293 }
294
295 /**
296  * Dequeue several objects from a ring (multi-consumers safe).
297  *
298  * This function uses a "compare and set" instruction to move the
299  * consumer index atomically.
300  *
301  * @param r
302  *   A pointer to the ring structure.
303  * @param obj_table
304  *   A pointer to a table of objects that will be filled.
305  * @param esize
306  *   The size of ring element, in bytes. It must be a multiple of 4.
307  *   This must be the same value used while creating the ring. Otherwise
308  *   the results are undefined.
309  * @param n
310  *   The number of objects to dequeue from the ring to the obj_table.
311  * @param available
312  *   If non-NULL, returns the number of remaining ring entries after the
313  *   dequeue has finished.
314  * @return
315  *   The number of objects dequeued, either 0 or n
316  */
317 static __rte_always_inline unsigned int
318 rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
319                 unsigned int esize, unsigned int n, unsigned int *available)
320 {
321         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
322                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
323 }
324
325 /**
326  * Dequeue several objects from a ring (NOT multi-consumers safe).
327  *
328  * @param r
329  *   A pointer to the ring structure.
330  * @param obj_table
331  *   A pointer to a table of objects that will be filled.
332  * @param esize
333  *   The size of ring element, in bytes. It must be a multiple of 4.
334  *   This must be the same value used while creating the ring. Otherwise
335  *   the results are undefined.
336  * @param n
337  *   The number of objects to dequeue from the ring to the obj_table,
338  *   must be strictly positive.
339  * @param available
340  *   If non-NULL, returns the number of remaining ring entries after the
341  *   dequeue has finished.
342  * @return
343  *   The number of objects dequeued, either 0 or n
344  */
345 static __rte_always_inline unsigned int
346 rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
347                 unsigned int esize, unsigned int n, unsigned int *available)
348 {
349         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
350                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
351 }
352
353 /**
354  * Dequeue several objects from a ring.
355  *
356  * This function calls the multi-consumers or the single-consumer
357  * version, depending on the default behaviour that was specified at
358  * ring creation time (see flags).
359  *
360  * @param r
361  *   A pointer to the ring structure.
362  * @param obj_table
363  *   A pointer to a table of objects that will be filled.
364  * @param esize
365  *   The size of ring element, in bytes. It must be a multiple of 4.
366  *   This must be the same value used while creating the ring. Otherwise
367  *   the results are undefined.
368  * @param n
369  *   The number of objects to dequeue from the ring to the obj_table.
370  * @param available
371  *   If non-NULL, returns the number of remaining ring entries after the
372  *   dequeue has finished.
373  * @return
374  *   The number of objects dequeued, either 0 or n
375  */
376 static __rte_always_inline unsigned int
377 rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
378                 unsigned int esize, unsigned int n, unsigned int *available)
379 {
380         switch (r->cons.sync_type) {
381         case RTE_RING_SYNC_MT:
382                 return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
383                         available);
384         case RTE_RING_SYNC_ST:
385                 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
386                         available);
387         case RTE_RING_SYNC_MT_RTS:
388                 return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
389                         n, available);
390         case RTE_RING_SYNC_MT_HTS:
391                 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
392                         n, available);
393         }
394
395         /* valid ring should never reach this point */
396         RTE_ASSERT(0);
397         if (available != NULL)
398                 *available = 0;
399         return 0;
400 }
401
402 /**
403  * Dequeue one object from a ring (multi-consumers safe).
404  *
405  * This function uses a "compare and set" instruction to move the
406  * consumer index atomically.
407  *
408  * @param r
409  *   A pointer to the ring structure.
410  * @param obj_p
411  *   A pointer to the object that will be filled.
412  * @param esize
413  *   The size of ring element, in bytes. It must be a multiple of 4.
414  *   This must be the same value used while creating the ring. Otherwise
415  *   the results are undefined.
416  * @return
417  *   - 0: Success; objects dequeued.
418  *   - -ENOENT: Not enough entries in the ring to dequeue; no object is
419  *     dequeued.
420  */
421 static __rte_always_inline int
422 rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
423                                 unsigned int esize)
424 {
425         return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL)  ? 0 :
426                                                                 -ENOENT;
427 }
428
429 /**
430  * Dequeue one object from a ring (NOT multi-consumers safe).
431  *
432  * @param r
433  *   A pointer to the ring structure.
434  * @param obj_p
435  *   A pointer to the object that will be filled.
436  * @param esize
437  *   The size of ring element, in bytes. It must be a multiple of 4.
438  *   This must be the same value used while creating the ring. Otherwise
439  *   the results are undefined.
440  * @return
441  *   - 0: Success; objects dequeued.
442  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
443  *     dequeued.
444  */
445 static __rte_always_inline int
446 rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
447                                 unsigned int esize)
448 {
449         return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
450                                                                 -ENOENT;
451 }
452
453 /**
454  * Dequeue one object from a ring.
455  *
456  * This function calls the multi-consumers or the single-consumer
457  * version depending on the default behaviour that was specified at
458  * ring creation time (see flags).
459  *
460  * @param r
461  *   A pointer to the ring structure.
462  * @param obj_p
463  *   A pointer to the object that will be filled.
464  * @param esize
465  *   The size of ring element, in bytes. It must be a multiple of 4.
466  *   This must be the same value used while creating the ring. Otherwise
467  *   the results are undefined.
468  * @return
469  *   - 0: Success, objects dequeued.
470  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
471  *     dequeued.
472  */
473 static __rte_always_inline int
474 rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
475 {
476         return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
477                                                                 -ENOENT;
478 }
479
480 /**
481  * Enqueue several objects on the ring (multi-producers safe).
482  *
483  * This function uses a "compare and set" instruction to move the
484  * producer index atomically.
485  *
486  * @param r
487  *   A pointer to the ring structure.
488  * @param obj_table
489  *   A pointer to a table of objects.
490  * @param esize
491  *   The size of ring element, in bytes. It must be a multiple of 4.
492  *   This must be the same value used while creating the ring. Otherwise
493  *   the results are undefined.
494  * @param n
495  *   The number of objects to add in the ring from the obj_table.
496  * @param free_space
497  *   if non-NULL, returns the amount of space in the ring after the
498  *   enqueue operation has finished.
499  * @return
500  *   - n: Actual number of objects enqueued.
501  */
502 static __rte_always_inline unsigned int
503 rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
504                 unsigned int esize, unsigned int n, unsigned int *free_space)
505 {
506         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
507                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
508 }
509
510 /**
511  * Enqueue several objects on a ring
512  *
513  * @warning This API is NOT multi-producers safe
514  *
515  * @param r
516  *   A pointer to the ring structure.
517  * @param obj_table
518  *   A pointer to a table of objects.
519  * @param esize
520  *   The size of ring element, in bytes. It must be a multiple of 4.
521  *   This must be the same value used while creating the ring. Otherwise
522  *   the results are undefined.
523  * @param n
524  *   The number of objects to add in the ring from the obj_table.
525  * @param free_space
526  *   if non-NULL, returns the amount of space in the ring after the
527  *   enqueue operation has finished.
528  * @return
529  *   - n: Actual number of objects enqueued.
530  */
531 static __rte_always_inline unsigned int
532 rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
533                 unsigned int esize, unsigned int n, unsigned int *free_space)
534 {
535         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
536                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
537 }
538
539 /**
540  * Enqueue several objects on a ring.
541  *
542  * This function calls the multi-producer or the single-producer
543  * version depending on the default behavior that was specified at
544  * ring creation time (see flags).
545  *
546  * @param r
547  *   A pointer to the ring structure.
548  * @param obj_table
549  *   A pointer to a table of objects.
550  * @param esize
551  *   The size of ring element, in bytes. It must be a multiple of 4.
552  *   This must be the same value used while creating the ring. Otherwise
553  *   the results are undefined.
554  * @param n
555  *   The number of objects to add in the ring from the obj_table.
556  * @param free_space
557  *   if non-NULL, returns the amount of space in the ring after the
558  *   enqueue operation has finished.
559  * @return
560  *   - n: Actual number of objects enqueued.
561  */
562 static __rte_always_inline unsigned int
563 rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
564                 unsigned int esize, unsigned int n, unsigned int *free_space)
565 {
566         switch (r->prod.sync_type) {
567         case RTE_RING_SYNC_MT:
568                 return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
569                         free_space);
570         case RTE_RING_SYNC_ST:
571                 return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
572                         free_space);
573         case RTE_RING_SYNC_MT_RTS:
574                 return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
575                         n, free_space);
576         case RTE_RING_SYNC_MT_HTS:
577                 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
578                         n, free_space);
579         }
580
581         /* valid ring should never reach this point */
582         RTE_ASSERT(0);
583         if (free_space != NULL)
584                 *free_space = 0;
585         return 0;
586 }
587
588 /**
589  * Dequeue several objects from a ring (multi-consumers safe). When the request
590  * objects are more than the available objects, only dequeue the actual number
591  * of objects
592  *
593  * This function uses a "compare and set" instruction to move the
594  * consumer index atomically.
595  *
596  * @param r
597  *   A pointer to the ring structure.
598  * @param obj_table
599  *   A pointer to a table of objects that will be filled.
600  * @param esize
601  *   The size of ring element, in bytes. It must be a multiple of 4.
602  *   This must be the same value used while creating the ring. Otherwise
603  *   the results are undefined.
604  * @param n
605  *   The number of objects to dequeue from the ring to the obj_table.
606  * @param available
607  *   If non-NULL, returns the number of remaining ring entries after the
608  *   dequeue has finished.
609  * @return
610  *   - n: Actual number of objects dequeued, 0 if ring is empty
611  */
612 static __rte_always_inline unsigned int
613 rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
614                 unsigned int esize, unsigned int n, unsigned int *available)
615 {
616         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
617                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
618 }
619
620 /**
621  * Dequeue several objects from a ring (NOT multi-consumers safe).When the
622  * request objects are more than the available objects, only dequeue the
623  * actual number of objects
624  *
625  * @param r
626  *   A pointer to the ring structure.
627  * @param obj_table
628  *   A pointer to a table of objects that will be filled.
629  * @param esize
630  *   The size of ring element, in bytes. It must be a multiple of 4.
631  *   This must be the same value used while creating the ring. Otherwise
632  *   the results are undefined.
633  * @param n
634  *   The number of objects to dequeue from the ring to the obj_table.
635  * @param available
636  *   If non-NULL, returns the number of remaining ring entries after the
637  *   dequeue has finished.
638  * @return
639  *   - n: Actual number of objects dequeued, 0 if ring is empty
640  */
641 static __rte_always_inline unsigned int
642 rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
643                 unsigned int esize, unsigned int n, unsigned int *available)
644 {
645         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
646                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
647 }
648
649 /**
650  * Dequeue multiple objects from a ring up to a maximum number.
651  *
652  * This function calls the multi-consumers or the single-consumer
653  * version, depending on the default behaviour that was specified at
654  * ring creation time (see flags).
655  *
656  * @param r
657  *   A pointer to the ring structure.
658  * @param obj_table
659  *   A pointer to a table of objects that will be filled.
660  * @param esize
661  *   The size of ring element, in bytes. It must be a multiple of 4.
662  *   This must be the same value used while creating the ring. Otherwise
663  *   the results are undefined.
664  * @param n
665  *   The number of objects to dequeue from the ring to the obj_table.
666  * @param available
667  *   If non-NULL, returns the number of remaining ring entries after the
668  *   dequeue has finished.
669  * @return
670  *   - Number of objects dequeued
671  */
672 static __rte_always_inline unsigned int
673 rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
674                 unsigned int esize, unsigned int n, unsigned int *available)
675 {
676         switch (r->cons.sync_type) {
677         case RTE_RING_SYNC_MT:
678                 return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
679                         available);
680         case RTE_RING_SYNC_ST:
681                 return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
682                         available);
683         case RTE_RING_SYNC_MT_RTS:
684                 return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
685                         n, available);
686         case RTE_RING_SYNC_MT_HTS:
687                 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
688                         n, available);
689         }
690
691         /* valid ring should never reach this point */
692         RTE_ASSERT(0);
693         if (available != NULL)
694                 *available = 0;
695         return 0;
696 }
697
698 #include <rte_ring_peek.h>
699 #include <rte_ring_peek_zc.h>
700
701 #include <rte_ring.h>
702
703 #ifdef __cplusplus
704 }
705 #endif
706
707 #endif /* _RTE_RING_ELEM_H_ */