35ee4491c67352c8107aa3ee07329a23f24558f3
[dpdk.git] / lib / librte_ring / rte_ring.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2010-2017 Intel Corporation
4  * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
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  *
29  * Note: the ring implementation is not preemptible. Refer to Programmer's
30  * guide/Environment Abstraction Layer/Multiple pthread/Known Issues/rte_ring
31  * for more information.
32  *
33  */
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 #include <rte_ring_core.h>
40
41 /**
42  * Calculate the memory size needed for a ring
43  *
44  * This function returns the number of bytes needed for a ring, given
45  * the number of elements in it. This value is the sum of the size of
46  * the structure rte_ring and the size of the memory needed by the
47  * objects pointers. The value is aligned to a cache line size.
48  *
49  * @param count
50  *   The number of elements in the ring (must be a power of 2).
51  * @return
52  *   - The memory size needed for the ring on success.
53  *   - -EINVAL if count is not a power of 2.
54  */
55 ssize_t rte_ring_get_memsize(unsigned count);
56
57 /**
58  * Initialize a ring structure.
59  *
60  * Initialize a ring structure in memory pointed by "r". The size of the
61  * memory area must be large enough to store the ring structure and the
62  * object table. It is advised to use rte_ring_get_memsize() to get the
63  * appropriate size.
64  *
65  * The ring size is set to *count*, which must be a power of two. Water
66  * marking is disabled by default. The real usable ring size is
67  * *count-1* instead of *count* to differentiate a free ring from an
68  * empty ring.
69  *
70  * The ring is not added in RTE_TAILQ_RING global list. Indeed, the
71  * memory given by the caller may not be shareable among dpdk
72  * processes.
73  *
74  * @param r
75  *   The pointer to the ring structure followed by the objects table.
76  * @param name
77  *   The name of the ring.
78  * @param count
79  *   The number of elements in the ring (must be a power of 2).
80  * @param flags
81  *   An OR of the following:
82  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
83  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
84  *      is "single-producer". Otherwise, it is "multi-producers".
85  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
86  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
87  *      is "single-consumer". Otherwise, it is "multi-consumers".
88  * @return
89  *   0 on success, or a negative value on error.
90  */
91 int rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
92         unsigned flags);
93
94 /**
95  * Create a new ring named *name* in memory.
96  *
97  * This function uses ``memzone_reserve()`` to allocate memory. Then it
98  * calls rte_ring_init() to initialize an empty ring.
99  *
100  * The new ring size is set to *count*, which must be a power of
101  * two. Water marking is disabled by default. The real usable ring size
102  * is *count-1* instead of *count* to differentiate a free ring from an
103  * empty ring.
104  *
105  * The ring is added in RTE_TAILQ_RING list.
106  *
107  * @param name
108  *   The name of the ring.
109  * @param count
110  *   The size of the ring (must be a power of 2).
111  * @param socket_id
112  *   The *socket_id* argument is the socket identifier in case of
113  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
114  *   constraint for the reserved zone.
115  * @param flags
116  *   An OR of the following:
117  *    - RING_F_SP_ENQ: If this flag is set, the default behavior when
118  *      using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
119  *      is "single-producer". Otherwise, it is "multi-producers".
120  *    - RING_F_SC_DEQ: If this flag is set, the default behavior when
121  *      using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
122  *      is "single-consumer". Otherwise, it is "multi-consumers".
123  * @return
124  *   On success, the pointer to the new allocated ring. NULL on error with
125  *    rte_errno set appropriately. Possible errno values include:
126  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
127  *    - E_RTE_SECONDARY - function was called from a secondary process instance
128  *    - EINVAL - count provided is not a power of 2
129  *    - ENOSPC - the maximum number of memzones has already been allocated
130  *    - EEXIST - a memzone with the same name already exists
131  *    - ENOMEM - no appropriate memory area found in which to create memzone
132  */
133 struct rte_ring *rte_ring_create(const char *name, unsigned count,
134                                  int socket_id, unsigned flags);
135
136 /**
137  * De-allocate all memory used by the ring.
138  *
139  * @param r
140  *   Ring to free
141  */
142 void rte_ring_free(struct rte_ring *r);
143
144 /**
145  * Dump the status of the ring to a file.
146  *
147  * @param f
148  *   A pointer to a file for output
149  * @param r
150  *   A pointer to the ring structure.
151  */
152 void rte_ring_dump(FILE *f, const struct rte_ring *r);
153
154 /* the actual enqueue of pointers on the ring.
155  * Placed here since identical code needed in both
156  * single and multi producer enqueue functions */
157 #define ENQUEUE_PTRS(r, ring_start, prod_head, obj_table, n, obj_type) do { \
158         unsigned int i; \
159         const uint32_t size = (r)->size; \
160         uint32_t idx = prod_head & (r)->mask; \
161         obj_type *ring = (obj_type *)ring_start; \
162         if (likely(idx + n < size)) { \
163                 for (i = 0; i < (n & ((~(unsigned)0x3))); i+=4, idx+=4) { \
164                         ring[idx] = obj_table[i]; \
165                         ring[idx+1] = obj_table[i+1]; \
166                         ring[idx+2] = obj_table[i+2]; \
167                         ring[idx+3] = obj_table[i+3]; \
168                 } \
169                 switch (n & 0x3) { \
170                 case 3: \
171                         ring[idx++] = obj_table[i++]; /* fallthrough */ \
172                 case 2: \
173                         ring[idx++] = obj_table[i++]; /* fallthrough */ \
174                 case 1: \
175                         ring[idx++] = obj_table[i++]; \
176                 } \
177         } else { \
178                 for (i = 0; idx < size; i++, idx++)\
179                         ring[idx] = obj_table[i]; \
180                 for (idx = 0; i < n; i++, idx++) \
181                         ring[idx] = obj_table[i]; \
182         } \
183 } while (0)
184
185 /* the actual copy of pointers on the ring to obj_table.
186  * Placed here since identical code needed in both
187  * single and multi consumer dequeue functions */
188 #define DEQUEUE_PTRS(r, ring_start, cons_head, obj_table, n, obj_type) do { \
189         unsigned int i; \
190         uint32_t idx = cons_head & (r)->mask; \
191         const uint32_t size = (r)->size; \
192         obj_type *ring = (obj_type *)ring_start; \
193         if (likely(idx + n < size)) { \
194                 for (i = 0; i < (n & (~(unsigned)0x3)); i+=4, idx+=4) {\
195                         obj_table[i] = ring[idx]; \
196                         obj_table[i+1] = ring[idx+1]; \
197                         obj_table[i+2] = ring[idx+2]; \
198                         obj_table[i+3] = ring[idx+3]; \
199                 } \
200                 switch (n & 0x3) { \
201                 case 3: \
202                         obj_table[i++] = ring[idx++]; /* fallthrough */ \
203                 case 2: \
204                         obj_table[i++] = ring[idx++]; /* fallthrough */ \
205                 case 1: \
206                         obj_table[i++] = ring[idx++]; \
207                 } \
208         } else { \
209                 for (i = 0; idx < size; i++, idx++) \
210                         obj_table[i] = ring[idx]; \
211                 for (idx = 0; i < n; i++, idx++) \
212                         obj_table[i] = ring[idx]; \
213         } \
214 } while (0)
215
216 /* Between load and load. there might be cpu reorder in weak model
217  * (powerpc/arm).
218  * There are 2 choices for the users
219  * 1.use rmb() memory barrier
220  * 2.use one-direction load_acquire/store_release barrier,defined by
221  * CONFIG_RTE_USE_C11_MEM_MODEL=y
222  * It depends on performance test results.
223  * By default, move common functions to rte_ring_generic.h
224  */
225 #ifdef RTE_USE_C11_MEM_MODEL
226 #include "rte_ring_c11_mem.h"
227 #else
228 #include "rte_ring_generic.h"
229 #endif
230
231 /**
232  * @internal Enqueue several objects on the ring
233  *
234   * @param r
235  *   A pointer to the ring structure.
236  * @param obj_table
237  *   A pointer to a table of void * pointers (objects).
238  * @param n
239  *   The number of objects to add in the ring from the obj_table.
240  * @param behavior
241  *   RTE_RING_QUEUE_FIXED:    Enqueue a fixed number of items from a ring
242  *   RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
243  * @param is_sp
244  *   Indicates whether to use single producer or multi-producer head update
245  * @param free_space
246  *   returns the amount of space after the enqueue operation has finished
247  * @return
248  *   Actual number of objects enqueued.
249  *   If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
250  */
251 static __rte_always_inline unsigned int
252 __rte_ring_do_enqueue(struct rte_ring *r, void * const *obj_table,
253                  unsigned int n, enum rte_ring_queue_behavior behavior,
254                  unsigned int is_sp, unsigned int *free_space)
255 {
256         uint32_t prod_head, prod_next;
257         uint32_t free_entries;
258
259         n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
260                         &prod_head, &prod_next, &free_entries);
261         if (n == 0)
262                 goto end;
263
264         ENQUEUE_PTRS(r, &r[1], prod_head, obj_table, n, void *);
265
266         update_tail(&r->prod, prod_head, prod_next, is_sp, 1);
267 end:
268         if (free_space != NULL)
269                 *free_space = free_entries - n;
270         return n;
271 }
272
273 /**
274  * @internal Dequeue several objects from the ring
275  *
276  * @param r
277  *   A pointer to the ring structure.
278  * @param obj_table
279  *   A pointer to a table of void * pointers (objects).
280  * @param n
281  *   The number of objects to pull from the ring.
282  * @param behavior
283  *   RTE_RING_QUEUE_FIXED:    Dequeue a fixed number of items from a ring
284  *   RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
285  * @param is_sc
286  *   Indicates whether to use single consumer or multi-consumer head update
287  * @param available
288  *   returns the number of remaining ring entries after the dequeue has finished
289  * @return
290  *   - Actual number of objects dequeued.
291  *     If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
292  */
293 static __rte_always_inline unsigned int
294 __rte_ring_do_dequeue(struct rte_ring *r, void **obj_table,
295                  unsigned int n, enum rte_ring_queue_behavior behavior,
296                  unsigned int is_sc, unsigned int *available)
297 {
298         uint32_t cons_head, cons_next;
299         uint32_t entries;
300
301         n = __rte_ring_move_cons_head(r, (int)is_sc, n, behavior,
302                         &cons_head, &cons_next, &entries);
303         if (n == 0)
304                 goto end;
305
306         DEQUEUE_PTRS(r, &r[1], cons_head, obj_table, n, void *);
307
308         update_tail(&r->cons, cons_head, cons_next, is_sc, 0);
309
310 end:
311         if (available != NULL)
312                 *available = entries - n;
313         return n;
314 }
315
316 /**
317  * Enqueue several objects on the ring (multi-producers safe).
318  *
319  * This function uses a "compare and set" instruction to move the
320  * producer index atomically.
321  *
322  * @param r
323  *   A pointer to the ring structure.
324  * @param obj_table
325  *   A pointer to a table of void * pointers (objects).
326  * @param n
327  *   The number of objects to add in the ring from the obj_table.
328  * @param free_space
329  *   if non-NULL, returns the amount of space in the ring after the
330  *   enqueue operation has finished.
331  * @return
332  *   The number of objects enqueued, either 0 or n
333  */
334 static __rte_always_inline unsigned int
335 rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
336                          unsigned int n, unsigned int *free_space)
337 {
338         return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
339                         RTE_RING_SYNC_MT, free_space);
340 }
341
342 /**
343  * Enqueue several objects on a ring (NOT multi-producers safe).
344  *
345  * @param r
346  *   A pointer to the ring structure.
347  * @param obj_table
348  *   A pointer to a table of void * pointers (objects).
349  * @param n
350  *   The number of objects to add in the ring from the obj_table.
351  * @param free_space
352  *   if non-NULL, returns the amount of space in the ring after the
353  *   enqueue operation has finished.
354  * @return
355  *   The number of objects enqueued, either 0 or n
356  */
357 static __rte_always_inline unsigned int
358 rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
359                          unsigned int n, unsigned int *free_space)
360 {
361         return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
362                         RTE_RING_SYNC_ST, free_space);
363 }
364
365 #ifdef ALLOW_EXPERIMENTAL_API
366 #include <rte_ring_elem.h>
367 #endif
368
369 /**
370  * Enqueue several objects on a ring.
371  *
372  * This function calls the multi-producer or the single-producer
373  * version depending on the default behavior that was specified at
374  * ring creation time (see flags).
375  *
376  * @param r
377  *   A pointer to the ring structure.
378  * @param obj_table
379  *   A pointer to a table of void * pointers (objects).
380  * @param n
381  *   The number of objects to add in the ring from the obj_table.
382  * @param free_space
383  *   if non-NULL, returns the amount of space in the ring after the
384  *   enqueue operation has finished.
385  * @return
386  *   The number of objects enqueued, either 0 or n
387  */
388 static __rte_always_inline unsigned int
389 rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
390                       unsigned int n, unsigned int *free_space)
391 {
392         return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
393                         r->prod.sync_type, free_space);
394 }
395
396 /**
397  * Enqueue one object on a ring (multi-producers safe).
398  *
399  * This function uses a "compare and set" instruction to move the
400  * producer index atomically.
401  *
402  * @param r
403  *   A pointer to the ring structure.
404  * @param obj
405  *   A pointer to the object to be added.
406  * @return
407  *   - 0: Success; objects enqueued.
408  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
409  */
410 static __rte_always_inline int
411 rte_ring_mp_enqueue(struct rte_ring *r, void *obj)
412 {
413         return rte_ring_mp_enqueue_bulk(r, &obj, 1, NULL) ? 0 : -ENOBUFS;
414 }
415
416 /**
417  * Enqueue one object on a ring (NOT multi-producers safe).
418  *
419  * @param r
420  *   A pointer to the ring structure.
421  * @param obj
422  *   A pointer to the object to be added.
423  * @return
424  *   - 0: Success; objects enqueued.
425  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
426  */
427 static __rte_always_inline int
428 rte_ring_sp_enqueue(struct rte_ring *r, void *obj)
429 {
430         return rte_ring_sp_enqueue_bulk(r, &obj, 1, NULL) ? 0 : -ENOBUFS;
431 }
432
433 /**
434  * Enqueue one object on a ring.
435  *
436  * This function calls the multi-producer or the single-producer
437  * version, depending on the default behaviour that was specified at
438  * ring creation time (see flags).
439  *
440  * @param r
441  *   A pointer to the ring structure.
442  * @param obj
443  *   A pointer to the object to be added.
444  * @return
445  *   - 0: Success; objects enqueued.
446  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
447  */
448 static __rte_always_inline int
449 rte_ring_enqueue(struct rte_ring *r, void *obj)
450 {
451         return rte_ring_enqueue_bulk(r, &obj, 1, NULL) ? 0 : -ENOBUFS;
452 }
453
454 /**
455  * Dequeue several objects from a ring (multi-consumers safe).
456  *
457  * This function uses a "compare and set" instruction to move the
458  * consumer index atomically.
459  *
460  * @param r
461  *   A pointer to the ring structure.
462  * @param obj_table
463  *   A pointer to a table of void * pointers (objects) that will be filled.
464  * @param n
465  *   The number of objects to dequeue from the ring to the obj_table.
466  * @param available
467  *   If non-NULL, returns the number of remaining ring entries after the
468  *   dequeue has finished.
469  * @return
470  *   The number of objects dequeued, either 0 or n
471  */
472 static __rte_always_inline unsigned int
473 rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
474                 unsigned int n, unsigned int *available)
475 {
476         return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
477                         RTE_RING_SYNC_MT, available);
478 }
479
480 /**
481  * Dequeue several objects from a ring (NOT multi-consumers safe).
482  *
483  * @param r
484  *   A pointer to the ring structure.
485  * @param obj_table
486  *   A pointer to a table of void * pointers (objects) that will be filled.
487  * @param n
488  *   The number of objects to dequeue from the ring to the obj_table,
489  *   must be strictly positive.
490  * @param available
491  *   If non-NULL, returns the number of remaining ring entries after the
492  *   dequeue has finished.
493  * @return
494  *   The number of objects dequeued, either 0 or n
495  */
496 static __rte_always_inline unsigned int
497 rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
498                 unsigned int n, unsigned int *available)
499 {
500         return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
501                         RTE_RING_SYNC_ST, available);
502 }
503
504 /**
505  * Dequeue several objects from a ring.
506  *
507  * This function calls the multi-consumers or the single-consumer
508  * version, depending on the default behaviour that was specified at
509  * ring creation time (see flags).
510  *
511  * @param r
512  *   A pointer to the ring structure.
513  * @param obj_table
514  *   A pointer to a table of void * pointers (objects) that will be filled.
515  * @param n
516  *   The number of objects to dequeue from the ring to the obj_table.
517  * @param available
518  *   If non-NULL, returns the number of remaining ring entries after the
519  *   dequeue has finished.
520  * @return
521  *   The number of objects dequeued, either 0 or n
522  */
523 static __rte_always_inline unsigned int
524 rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
525                 unsigned int *available)
526 {
527         return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
528                                 r->cons.sync_type, available);
529 }
530
531 /**
532  * Dequeue one object from a ring (multi-consumers safe).
533  *
534  * This function uses a "compare and set" instruction to move the
535  * consumer index atomically.
536  *
537  * @param r
538  *   A pointer to the ring structure.
539  * @param obj_p
540  *   A pointer to a void * pointer (object) that will be filled.
541  * @return
542  *   - 0: Success; objects dequeued.
543  *   - -ENOENT: Not enough entries in the ring to dequeue; no object is
544  *     dequeued.
545  */
546 static __rte_always_inline int
547 rte_ring_mc_dequeue(struct rte_ring *r, void **obj_p)
548 {
549         return rte_ring_mc_dequeue_bulk(r, obj_p, 1, NULL)  ? 0 : -ENOENT;
550 }
551
552 /**
553  * Dequeue one object from a ring (NOT multi-consumers safe).
554  *
555  * @param r
556  *   A pointer to the ring structure.
557  * @param obj_p
558  *   A pointer to a void * pointer (object) that will be filled.
559  * @return
560  *   - 0: Success; objects dequeued.
561  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
562  *     dequeued.
563  */
564 static __rte_always_inline int
565 rte_ring_sc_dequeue(struct rte_ring *r, void **obj_p)
566 {
567         return rte_ring_sc_dequeue_bulk(r, obj_p, 1, NULL) ? 0 : -ENOENT;
568 }
569
570 /**
571  * Dequeue one object from a ring.
572  *
573  * This function calls the multi-consumers or the single-consumer
574  * version depending on the default behaviour that was specified at
575  * ring creation time (see flags).
576  *
577  * @param r
578  *   A pointer to the ring structure.
579  * @param obj_p
580  *   A pointer to a void * pointer (object) that will be filled.
581  * @return
582  *   - 0: Success, objects dequeued.
583  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
584  *     dequeued.
585  */
586 static __rte_always_inline int
587 rte_ring_dequeue(struct rte_ring *r, void **obj_p)
588 {
589         return rte_ring_dequeue_bulk(r, obj_p, 1, NULL) ? 0 : -ENOENT;
590 }
591
592 /**
593  * Flush a ring.
594  *
595  * This function flush all the elements in a ring
596  *
597  * @b EXPERIMENTAL: this API may change without prior notice
598  *
599  * @warning
600  * Make sure the ring is not in use while calling this function.
601  *
602  * @param r
603  *   A pointer to the ring structure.
604  */
605 __rte_experimental
606 void
607 rte_ring_reset(struct rte_ring *r);
608
609 /**
610  * Return the number of entries in a ring.
611  *
612  * @param r
613  *   A pointer to the ring structure.
614  * @return
615  *   The number of entries in the ring.
616  */
617 static inline unsigned
618 rte_ring_count(const struct rte_ring *r)
619 {
620         uint32_t prod_tail = r->prod.tail;
621         uint32_t cons_tail = r->cons.tail;
622         uint32_t count = (prod_tail - cons_tail) & r->mask;
623         return (count > r->capacity) ? r->capacity : count;
624 }
625
626 /**
627  * Return the number of free entries in a ring.
628  *
629  * @param r
630  *   A pointer to the ring structure.
631  * @return
632  *   The number of free entries in the ring.
633  */
634 static inline unsigned
635 rte_ring_free_count(const struct rte_ring *r)
636 {
637         return r->capacity - rte_ring_count(r);
638 }
639
640 /**
641  * Test if a ring is full.
642  *
643  * @param r
644  *   A pointer to the ring structure.
645  * @return
646  *   - 1: The ring is full.
647  *   - 0: The ring is not full.
648  */
649 static inline int
650 rte_ring_full(const struct rte_ring *r)
651 {
652         return rte_ring_free_count(r) == 0;
653 }
654
655 /**
656  * Test if a ring is empty.
657  *
658  * @param r
659  *   A pointer to the ring structure.
660  * @return
661  *   - 1: The ring is empty.
662  *   - 0: The ring is not empty.
663  */
664 static inline int
665 rte_ring_empty(const struct rte_ring *r)
666 {
667         return rte_ring_count(r) == 0;
668 }
669
670 /**
671  * Return the size of the ring.
672  *
673  * @param r
674  *   A pointer to the ring structure.
675  * @return
676  *   The size of the data store used by the ring.
677  *   NOTE: this is not the same as the usable space in the ring. To query that
678  *   use ``rte_ring_get_capacity()``.
679  */
680 static inline unsigned int
681 rte_ring_get_size(const struct rte_ring *r)
682 {
683         return r->size;
684 }
685
686 /**
687  * Return the number of elements which can be stored in the ring.
688  *
689  * @param r
690  *   A pointer to the ring structure.
691  * @return
692  *   The usable size of the ring.
693  */
694 static inline unsigned int
695 rte_ring_get_capacity(const struct rte_ring *r)
696 {
697         return r->capacity;
698 }
699
700 /**
701  * Return sync type used by producer in the ring.
702  *
703  * @param r
704  *   A pointer to the ring structure.
705  * @return
706  *   Producer sync type value.
707  */
708 static inline enum rte_ring_sync_type
709 rte_ring_get_prod_sync_type(const struct rte_ring *r)
710 {
711         return r->prod.sync_type;
712 }
713
714 /**
715  * Check is the ring for single producer.
716  *
717  * @param r
718  *   A pointer to the ring structure.
719  * @return
720  *   true if ring is SP, zero otherwise.
721  */
722 static inline int
723 rte_ring_is_prod_single(const struct rte_ring *r)
724 {
725         return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
726 }
727
728 /**
729  * Return sync type used by consumer in the ring.
730  *
731  * @param r
732  *   A pointer to the ring structure.
733  * @return
734  *   Consumer sync type value.
735  */
736 static inline enum rte_ring_sync_type
737 rte_ring_get_cons_sync_type(const struct rte_ring *r)
738 {
739         return r->cons.sync_type;
740 }
741
742 /**
743  * Check is the ring for single consumer.
744  *
745  * @param r
746  *   A pointer to the ring structure.
747  * @return
748  *   true if ring is SC, zero otherwise.
749  */
750 static inline int
751 rte_ring_is_cons_single(const struct rte_ring *r)
752 {
753         return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
754 }
755
756 /**
757  * Dump the status of all rings on the console
758  *
759  * @param f
760  *   A pointer to a file for output
761  */
762 void rte_ring_list_dump(FILE *f);
763
764 /**
765  * Search a ring from its name
766  *
767  * @param name
768  *   The name of the ring.
769  * @return
770  *   The pointer to the ring matching the name, or NULL if not found,
771  *   with rte_errno set appropriately. Possible rte_errno values include:
772  *    - ENOENT - required entry not available to return.
773  */
774 struct rte_ring *rte_ring_lookup(const char *name);
775
776 /**
777  * Enqueue several objects on the ring (multi-producers safe).
778  *
779  * This function uses a "compare and set" instruction to move the
780  * producer index atomically.
781  *
782  * @param r
783  *   A pointer to the ring structure.
784  * @param obj_table
785  *   A pointer to a table of void * pointers (objects).
786  * @param n
787  *   The number of objects to add in the ring from the obj_table.
788  * @param free_space
789  *   if non-NULL, returns the amount of space in the ring after the
790  *   enqueue operation has finished.
791  * @return
792  *   - n: Actual number of objects enqueued.
793  */
794 static __rte_always_inline unsigned
795 rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
796                          unsigned int n, unsigned int *free_space)
797 {
798         return __rte_ring_do_enqueue(r, obj_table, n,
799                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
800 }
801
802 /**
803  * Enqueue several objects on a ring (NOT multi-producers safe).
804  *
805  * @param r
806  *   A pointer to the ring structure.
807  * @param obj_table
808  *   A pointer to a table of void * pointers (objects).
809  * @param n
810  *   The number of objects to add in the ring from the obj_table.
811  * @param free_space
812  *   if non-NULL, returns the amount of space in the ring after the
813  *   enqueue operation has finished.
814  * @return
815  *   - n: Actual number of objects enqueued.
816  */
817 static __rte_always_inline unsigned
818 rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
819                          unsigned int n, unsigned int *free_space)
820 {
821         return __rte_ring_do_enqueue(r, obj_table, n,
822                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
823 }
824
825 /**
826  * Enqueue several objects on a ring.
827  *
828  * This function calls the multi-producer or the single-producer
829  * version depending on the default behavior that was specified at
830  * ring creation time (see flags).
831  *
832  * @param r
833  *   A pointer to the ring structure.
834  * @param obj_table
835  *   A pointer to a table of void * pointers (objects).
836  * @param n
837  *   The number of objects to add in the ring from the obj_table.
838  * @param free_space
839  *   if non-NULL, returns the amount of space in the ring after the
840  *   enqueue operation has finished.
841  * @return
842  *   - n: Actual number of objects enqueued.
843  */
844 static __rte_always_inline unsigned
845 rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
846                       unsigned int n, unsigned int *free_space)
847 {
848         return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
849                         r->prod.sync_type, free_space);
850 }
851
852 /**
853  * Dequeue several objects from a ring (multi-consumers safe). When the request
854  * objects are more than the available objects, only dequeue the actual number
855  * of objects
856  *
857  * This function uses a "compare and set" instruction to move the
858  * consumer index atomically.
859  *
860  * @param r
861  *   A pointer to the ring structure.
862  * @param obj_table
863  *   A pointer to a table of void * pointers (objects) that will be filled.
864  * @param n
865  *   The number of objects to dequeue from the ring to the obj_table.
866  * @param available
867  *   If non-NULL, returns the number of remaining ring entries after the
868  *   dequeue has finished.
869  * @return
870  *   - n: Actual number of objects dequeued, 0 if ring is empty
871  */
872 static __rte_always_inline unsigned
873 rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
874                 unsigned int n, unsigned int *available)
875 {
876         return __rte_ring_do_dequeue(r, obj_table, n,
877                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
878 }
879
880 /**
881  * Dequeue several objects from a ring (NOT multi-consumers safe).When the
882  * request objects are more than the available objects, only dequeue the
883  * actual number of objects
884  *
885  * @param r
886  *   A pointer to the ring structure.
887  * @param obj_table
888  *   A pointer to a table of void * pointers (objects) that will be filled.
889  * @param n
890  *   The number of objects to dequeue from the ring to the obj_table.
891  * @param available
892  *   If non-NULL, returns the number of remaining ring entries after the
893  *   dequeue has finished.
894  * @return
895  *   - n: Actual number of objects dequeued, 0 if ring is empty
896  */
897 static __rte_always_inline unsigned
898 rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
899                 unsigned int n, unsigned int *available)
900 {
901         return __rte_ring_do_dequeue(r, obj_table, n,
902                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
903 }
904
905 /**
906  * Dequeue multiple objects from a ring up to a maximum number.
907  *
908  * This function calls the multi-consumers or the single-consumer
909  * version, depending on the default behaviour that was specified at
910  * ring creation time (see flags).
911  *
912  * @param r
913  *   A pointer to the ring structure.
914  * @param obj_table
915  *   A pointer to a table of void * pointers (objects) that will be filled.
916  * @param n
917  *   The number of objects to dequeue from the ring to the obj_table.
918  * @param available
919  *   If non-NULL, returns the number of remaining ring entries after the
920  *   dequeue has finished.
921  * @return
922  *   - Number of objects dequeued
923  */
924 static __rte_always_inline unsigned
925 rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
926                 unsigned int n, unsigned int *available)
927 {
928         return __rte_ring_do_dequeue(r, obj_table, n,
929                                 RTE_RING_QUEUE_VARIABLE,
930                                 r->cons.sync_type, available);
931 }
932
933 #ifdef __cplusplus
934 }
935 #endif
936
937 #endif /* _RTE_RING_H_ */