LCOV - code coverage report
Current view: top level - lib/ring - rte_ring.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 35 38 92.1 %
Date: 2025-01-02 22:41:34 Functions: 12 13 92.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 41 78 52.6 %

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

Generated by: LCOV version 1.14