LCOV - code coverage report
Current view: top level - lib/ring - rte_ring_elem.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 25 36 69.4 %
Date: 2025-01-02 22:41:34 Functions: 12 12 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 52 328 15.9 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *
       3                 :            :  * Copyright (c) 2019 Arm Limited
       4                 :            :  * Copyright (c) 2010-2017 Intel Corporation
       5                 :            :  * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
       6                 :            :  * All rights reserved.
       7                 :            :  * Derived from FreeBSD's bufring.h
       8                 :            :  * Used as BSD-3 Licensed with permission from Kip Macy.
       9                 :            :  */
      10                 :            : 
      11                 :            : #ifndef _RTE_RING_ELEM_H_
      12                 :            : #define _RTE_RING_ELEM_H_
      13                 :            : 
      14                 :            : /**
      15                 :            :  * @file
      16                 :            :  * RTE Ring with user defined element size
      17                 :            :  */
      18                 :            : 
      19                 :            : #include <rte_ring_core.h>
      20                 :            : #include <rte_ring_elem_pvt.h>
      21                 :            : 
      22                 :            : /**
      23                 :            :  * Calculate the memory size needed for a ring with given element size
      24                 :            :  *
      25                 :            :  * This function returns the number of bytes needed for a ring, given
      26                 :            :  * the number of elements in it and the size of the element. This value
      27                 :            :  * is the sum of the size of the structure rte_ring and the size of the
      28                 :            :  * memory needed for storing the elements. The value is aligned to a cache
      29                 :            :  * line size.
      30                 :            :  *
      31                 :            :  * @param esize
      32                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
      33                 :            :  * @param count
      34                 :            :  *   The number of elements in the ring (must be a power of 2).
      35                 :            :  * @return
      36                 :            :  *   - The memory size needed for the ring on success.
      37                 :            :  *   - -EINVAL - esize is not a multiple of 4 or count provided is not a
      38                 :            :  *               power of 2.
      39                 :            :  */
      40                 :            : ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
      41                 :            : 
      42                 :            : /**
      43                 :            :  * Create a new ring named *name* that stores elements with given size.
      44                 :            :  *
      45                 :            :  * This function uses ``memzone_reserve()`` to allocate memory. Then it
      46                 :            :  * calls rte_ring_init() to initialize an empty ring.
      47                 :            :  *
      48                 :            :  * The new ring size is set to *count*, which must be a power of
      49                 :            :  * two. Water marking is disabled by default. The real usable ring size
      50                 :            :  * is *count-1* instead of *count* to differentiate a full ring from an
      51                 :            :  * empty ring.
      52                 :            :  *
      53                 :            :  * The ring is added in RTE_TAILQ_RING list.
      54                 :            :  *
      55                 :            :  * @param name
      56                 :            :  *   The name of the ring.
      57                 :            :  * @param esize
      58                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
      59                 :            :  * @param count
      60                 :            :  *   The number of elements in the ring (must be a power of 2).
      61                 :            :  * @param socket_id
      62                 :            :  *   The *socket_id* argument is the socket identifier in case of
      63                 :            :  *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
      64                 :            :  *   constraint for the reserved zone.
      65                 :            :  * @param flags
      66                 :            :  *   An OR of the following:
      67                 :            :  *   - One of mutually exclusive flags that define producer behavior:
      68                 :            :  *      - RING_F_SP_ENQ: If this flag is set, the default behavior when
      69                 :            :  *        using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
      70                 :            :  *        is "single-producer".
      71                 :            :  *      - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
      72                 :            :  *        using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
      73                 :            :  *        is "multi-producer RTS mode".
      74                 :            :  *      - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when
      75                 :            :  *        using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
      76                 :            :  *        is "multi-producer HTS mode".
      77                 :            :  *     If none of these flags is set, then default "multi-producer"
      78                 :            :  *     behavior is selected.
      79                 :            :  *   - One of mutually exclusive flags that define consumer behavior:
      80                 :            :  *      - RING_F_SC_DEQ: If this flag is set, the default behavior when
      81                 :            :  *        using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
      82                 :            :  *        is "single-consumer". Otherwise, it is "multi-consumers".
      83                 :            :  *      - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
      84                 :            :  *        using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
      85                 :            :  *        is "multi-consumer RTS mode".
      86                 :            :  *      - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when
      87                 :            :  *        using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
      88                 :            :  *        is "multi-consumer HTS mode".
      89                 :            :  *     If none of these flags is set, then default "multi-consumer"
      90                 :            :  *     behavior is selected.
      91                 :            :  * @return
      92                 :            :  *   On success, the pointer to the new allocated ring. NULL on error with
      93                 :            :  *    rte_errno set appropriately. Possible errno values include:
      94                 :            :  *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
      95                 :            :  *    - EINVAL - esize is not a multiple of 4 or count provided is not a
      96                 :            :  *               power of 2.
      97                 :            :  *    - ENOSPC - the maximum number of memzones has already been allocated
      98                 :            :  *    - EEXIST - a memzone with the same name already exists
      99                 :            :  *    - ENOMEM - no appropriate memory area found in which to create memzone
     100                 :            :  */
     101                 :            : struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize,
     102                 :            :                         unsigned int count, int socket_id, unsigned int flags);
     103                 :            : 
     104                 :            : /**
     105                 :            :  * Enqueue several objects on the ring (multi-producers safe).
     106                 :            :  *
     107                 :            :  * This function uses a "compare and set" instruction to move the
     108                 :            :  * producer index atomically.
     109                 :            :  *
     110                 :            :  * @param r
     111                 :            :  *   A pointer to the ring structure.
     112                 :            :  * @param obj_table
     113                 :            :  *   A pointer to a table of objects.
     114                 :            :  * @param esize
     115                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     116                 :            :  *   This must be the same value used while creating the ring. Otherwise
     117                 :            :  *   the results are undefined.
     118                 :            :  * @param n
     119                 :            :  *   The number of objects to add in the ring from the obj_table.
     120                 :            :  * @param free_space
     121                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     122                 :            :  *   enqueue operation has finished.
     123                 :            :  * @return
     124                 :            :  *   The number of objects enqueued, either 0 or n
     125                 :            :  */
     126                 :            : static __rte_always_inline unsigned int
     127                 :       1108 : rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
     128                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     129                 :            : {
     130                 :       1108 :         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
     131                 :            :                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
     132                 :            : }
     133                 :            : 
     134                 :            : /**
     135                 :            :  * Enqueue several objects on a ring
     136                 :            :  *
     137                 :            :  * @warning This API is NOT multi-producers safe
     138                 :            :  *
     139                 :            :  * @param r
     140                 :            :  *   A pointer to the ring structure.
     141                 :            :  * @param obj_table
     142                 :            :  *   A pointer to a table of objects.
     143                 :            :  * @param esize
     144                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     145                 :            :  *   This must be the same value used while creating the ring. Otherwise
     146                 :            :  *   the results are undefined.
     147                 :            :  * @param n
     148                 :            :  *   The number of objects to add in the ring from the obj_table.
     149                 :            :  * @param free_space
     150                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     151                 :            :  *   enqueue operation has finished.
     152                 :            :  * @return
     153                 :            :  *   The number of objects enqueued, either 0 or n
     154                 :            :  */
     155                 :            : static __rte_always_inline unsigned int
     156                 :       1108 : rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
     157                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     158                 :            : {
     159                 :       1108 :         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
     160                 :            :                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
     161                 :            : }
     162                 :            : 
     163                 :            : #include <rte_ring_hts.h>
     164                 :            : #include <rte_ring_rts.h>
     165                 :            : 
     166                 :            : /**
     167                 :            :  * Enqueue several objects on a ring.
     168                 :            :  *
     169                 :            :  * This function calls the multi-producer or the single-producer
     170                 :            :  * version depending on the default behavior that was specified at
     171                 :            :  * ring creation time (see flags).
     172                 :            :  *
     173                 :            :  * @param r
     174                 :            :  *   A pointer to the ring structure.
     175                 :            :  * @param obj_table
     176                 :            :  *   A pointer to a table of objects.
     177                 :            :  * @param esize
     178                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     179                 :            :  *   This must be the same value used while creating the ring. Otherwise
     180                 :            :  *   the results are undefined.
     181                 :            :  * @param n
     182                 :            :  *   The number of objects to add in the ring from the obj_table.
     183                 :            :  * @param free_space
     184                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     185                 :            :  *   enqueue operation has finished.
     186                 :            :  * @return
     187                 :            :  *   The number of objects enqueued, either 0 or n
     188                 :            :  */
     189                 :            : static __rte_always_inline unsigned int
     190                 :       3324 : rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
     191                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     192                 :            : {
     193   [ -  +  +  -  :     292674 :         switch (r->prod.sync_type) {
          -  -  +  -  -  
          -  -  +  -  -  
          -  -  +  -  -  
          -  +  +  +  +  
          -  +  +  +  +  
          -  -  +  -  -  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     194                 :            :         case RTE_RING_SYNC_MT:
     195                 :            :                 return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
     196                 :            :                         free_space);
     197                 :            :         case RTE_RING_SYNC_ST:
     198                 :            :                 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
     199                 :            :                         free_space);
     200                 :            :         case RTE_RING_SYNC_MT_RTS:
     201                 :            :                 return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
     202                 :            :                         free_space);
     203                 :            :         case RTE_RING_SYNC_MT_HTS:
     204                 :            :                 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
     205                 :            :                         free_space);
     206                 :            :         }
     207                 :            : 
     208                 :            :         /* valid ring should never reach this point */
     209                 :            :         RTE_ASSERT(0);
     210   [ #  #  #  # ]:          0 :         if (free_space != NULL)
     211                 :          0 :                 *free_space = 0;
     212                 :            :         return 0;
     213                 :            : }
     214                 :            : 
     215                 :            : /**
     216                 :            :  * Enqueue one object on a ring (multi-producers safe).
     217                 :            :  *
     218                 :            :  * This function uses a "compare and set" instruction to move the
     219                 :            :  * producer index atomically.
     220                 :            :  *
     221                 :            :  * @param r
     222                 :            :  *   A pointer to the ring structure.
     223                 :            :  * @param obj
     224                 :            :  *   A pointer to the object to be added.
     225                 :            :  * @param esize
     226                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     227                 :            :  *   This must be the same value used while creating the ring. Otherwise
     228                 :            :  *   the results are undefined.
     229                 :            :  * @return
     230                 :            :  *   - 0: Success; objects enqueued.
     231                 :            :  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
     232                 :            :  */
     233                 :            : static __rte_always_inline int
     234                 :            : rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
     235                 :            : {
     236   [ #  #  #  # ]:          0 :         return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
     237                 :            :                                                                 -ENOBUFS;
     238                 :            : }
     239                 :            : 
     240                 :            : /**
     241                 :            :  * Enqueue one object on a ring
     242                 :            :  *
     243                 :            :  * @warning This API is NOT multi-producers safe
     244                 :            :  *
     245                 :            :  * @param r
     246                 :            :  *   A pointer to the ring structure.
     247                 :            :  * @param obj
     248                 :            :  *   A pointer to the object to be added.
     249                 :            :  * @param esize
     250                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     251                 :            :  *   This must be the same value used while creating the ring. Otherwise
     252                 :            :  *   the results are undefined.
     253                 :            :  * @return
     254                 :            :  *   - 0: Success; objects enqueued.
     255                 :            :  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
     256                 :            :  */
     257                 :            : static __rte_always_inline int
     258                 :            : rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
     259                 :            : {
     260                 :            :         return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
     261                 :            :                                                                 -ENOBUFS;
     262                 :            : }
     263                 :            : 
     264                 :            : /**
     265                 :            :  * Enqueue one object on a ring.
     266                 :            :  *
     267                 :            :  * This function calls the multi-producer or the single-producer
     268                 :            :  * version, depending on the default behaviour that was specified at
     269                 :            :  * ring creation time (see flags).
     270                 :            :  *
     271                 :            :  * @param r
     272                 :            :  *   A pointer to the ring structure.
     273                 :            :  * @param obj
     274                 :            :  *   A pointer to the object to be added.
     275                 :            :  * @param esize
     276                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     277                 :            :  *   This must be the same value used while creating the ring. Otherwise
     278                 :            :  *   the results are undefined.
     279                 :            :  * @return
     280                 :            :  *   - 0: Success; objects enqueued.
     281                 :            :  *   - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
     282                 :            :  */
     283                 :            : static __rte_always_inline int
     284                 :            : rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
     285                 :            : {
     286         [ +  + ]:       1055 :         return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
     287                 :            :                                                                 -ENOBUFS;
     288                 :            : }
     289                 :            : 
     290                 :            : /**
     291                 :            :  * Dequeue several objects from a ring (multi-consumers safe).
     292                 :            :  *
     293                 :            :  * This function uses a "compare and set" instruction to move the
     294                 :            :  * consumer index atomically.
     295                 :            :  *
     296                 :            :  * @param r
     297                 :            :  *   A pointer to the ring structure.
     298                 :            :  * @param obj_table
     299                 :            :  *   A pointer to a table of objects that will be filled.
     300                 :            :  * @param esize
     301                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     302                 :            :  *   This must be the same value used while creating the ring. Otherwise
     303                 :            :  *   the results are undefined.
     304                 :            :  * @param n
     305                 :            :  *   The number of objects to dequeue from the ring to the obj_table.
     306                 :            :  * @param available
     307                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     308                 :            :  *   dequeue has finished.
     309                 :            :  * @return
     310                 :            :  *   The number of objects dequeued, either 0 or n
     311                 :            :  */
     312                 :            : static __rte_always_inline unsigned int
     313                 :       1104 : rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
     314                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     315                 :            : {
     316                 :       1104 :         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
     317                 :            :                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
     318                 :            : }
     319                 :            : 
     320                 :            : /**
     321                 :            :  * Dequeue several objects from a ring (NOT multi-consumers safe).
     322                 :            :  *
     323                 :            :  * @param r
     324                 :            :  *   A pointer to the ring structure.
     325                 :            :  * @param obj_table
     326                 :            :  *   A pointer to a table of objects that will be filled.
     327                 :            :  * @param esize
     328                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     329                 :            :  *   This must be the same value used while creating the ring. Otherwise
     330                 :            :  *   the results are undefined.
     331                 :            :  * @param n
     332                 :            :  *   The number of objects to dequeue from the ring to the obj_table,
     333                 :            :  *   must be strictly positive.
     334                 :            :  * @param available
     335                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     336                 :            :  *   dequeue has finished.
     337                 :            :  * @return
     338                 :            :  *   The number of objects dequeued, either 0 or n
     339                 :            :  */
     340                 :            : static __rte_always_inline unsigned int
     341                 :       1104 : rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
     342                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     343                 :            : {
     344                 :       1104 :         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
     345                 :            :                         RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
     346                 :            : }
     347                 :            : 
     348                 :            : /**
     349                 :            :  * Dequeue several objects from a ring.
     350                 :            :  *
     351                 :            :  * This function calls the multi-consumers or the single-consumer
     352                 :            :  * version, depending on the default behaviour that was specified at
     353                 :            :  * ring creation time (see flags).
     354                 :            :  *
     355                 :            :  * @param r
     356                 :            :  *   A pointer to the ring structure.
     357                 :            :  * @param obj_table
     358                 :            :  *   A pointer to a table of objects that will be filled.
     359                 :            :  * @param esize
     360                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     361                 :            :  *   This must be the same value used while creating the ring. Otherwise
     362                 :            :  *   the results are undefined.
     363                 :            :  * @param n
     364                 :            :  *   The number of objects to dequeue from the ring to the obj_table.
     365                 :            :  * @param available
     366                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     367                 :            :  *   dequeue has finished.
     368                 :            :  * @return
     369                 :            :  *   The number of objects dequeued, either 0 or n
     370                 :            :  */
     371                 :            : static __rte_always_inline unsigned int
     372                 :       3312 : rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
     373                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     374                 :            : {
     375   [ +  +  -  -  :    3318559 :         switch (r->cons.sync_type) {
          -  -  +  -  -  
          -  -  +  -  -  
          -  -  +  -  -  
          -  +  +  +  +  
          -  +  +  +  +  
          -  -  +  -  -  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     376                 :            :         case RTE_RING_SYNC_MT:
     377                 :            :                 return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
     378                 :            :                         available);
     379                 :            :         case RTE_RING_SYNC_ST:
     380                 :            :                 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
     381                 :            :                         available);
     382                 :            :         case RTE_RING_SYNC_MT_RTS:
     383                 :            :                 return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
     384                 :            :                         n, available);
     385                 :            :         case RTE_RING_SYNC_MT_HTS:
     386                 :            :                 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
     387                 :            :                         n, available);
     388                 :            :         }
     389                 :            : 
     390                 :            :         /* valid ring should never reach this point */
     391                 :            :         RTE_ASSERT(0);
     392   [ #  #  #  # ]:          0 :         if (available != NULL)
     393                 :          0 :                 *available = 0;
     394                 :            :         return 0;
     395                 :            : }
     396                 :            : 
     397                 :            : /**
     398                 :            :  * Dequeue one object from a ring (multi-consumers safe).
     399                 :            :  *
     400                 :            :  * This function uses a "compare and set" instruction to move the
     401                 :            :  * consumer index atomically.
     402                 :            :  *
     403                 :            :  * @param r
     404                 :            :  *   A pointer to the ring structure.
     405                 :            :  * @param obj_p
     406                 :            :  *   A pointer to the object that will be filled.
     407                 :            :  * @param esize
     408                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     409                 :            :  *   This must be the same value used while creating the ring. Otherwise
     410                 :            :  *   the results are undefined.
     411                 :            :  * @return
     412                 :            :  *   - 0: Success; objects dequeued.
     413                 :            :  *   - -ENOENT: Not enough entries in the ring to dequeue; no object is
     414                 :            :  *     dequeued.
     415                 :            :  */
     416                 :            : static __rte_always_inline int
     417                 :            : rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
     418                 :            :                                 unsigned int esize)
     419                 :            : {
     420   [ #  #  #  # ]:          0 :         return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL)  ? 0 :
     421                 :            :                                                                 -ENOENT;
     422                 :            : }
     423                 :            : 
     424                 :            : /**
     425                 :            :  * Dequeue one object from a ring (NOT multi-consumers safe).
     426                 :            :  *
     427                 :            :  * @param r
     428                 :            :  *   A pointer to the ring structure.
     429                 :            :  * @param obj_p
     430                 :            :  *   A pointer to the object that will be filled.
     431                 :            :  * @param esize
     432                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     433                 :            :  *   This must be the same value used while creating the ring. Otherwise
     434                 :            :  *   the results are undefined.
     435                 :            :  * @return
     436                 :            :  *   - 0: Success; objects dequeued.
     437                 :            :  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
     438                 :            :  *     dequeued.
     439                 :            :  */
     440                 :            : static __rte_always_inline int
     441                 :            : rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
     442                 :            :                                 unsigned int esize)
     443                 :            : {
     444                 :            :         return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
     445                 :            :                                                                 -ENOENT;
     446                 :            : }
     447                 :            : 
     448                 :            : /**
     449                 :            :  * Dequeue one object from a ring.
     450                 :            :  *
     451                 :            :  * This function calls the multi-consumers or the single-consumer
     452                 :            :  * version depending on the default behaviour that was specified at
     453                 :            :  * ring creation time (see flags).
     454                 :            :  *
     455                 :            :  * @param r
     456                 :            :  *   A pointer to the ring structure.
     457                 :            :  * @param obj_p
     458                 :            :  *   A pointer to the object that will be filled.
     459                 :            :  * @param esize
     460                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     461                 :            :  *   This must be the same value used while creating the ring. Otherwise
     462                 :            :  *   the results are undefined.
     463                 :            :  * @return
     464                 :            :  *   - 0: Success, objects dequeued.
     465                 :            :  *   - -ENOENT: Not enough entries in the ring to dequeue, no object is
     466                 :            :  *     dequeued.
     467                 :            :  */
     468                 :            : static __rte_always_inline int
     469                 :            : rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
     470                 :            : {
     471         [ #  # ]:          0 :         return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
     472                 :            :                                                                 -ENOENT;
     473                 :            : }
     474                 :            : 
     475                 :            : /**
     476                 :            :  * Enqueue several objects on the ring (multi-producers safe).
     477                 :            :  *
     478                 :            :  * This function uses a "compare and set" instruction to move the
     479                 :            :  * producer index atomically.
     480                 :            :  *
     481                 :            :  * @param r
     482                 :            :  *   A pointer to the ring structure.
     483                 :            :  * @param obj_table
     484                 :            :  *   A pointer to a table of objects.
     485                 :            :  * @param esize
     486                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     487                 :            :  *   This must be the same value used while creating the ring. Otherwise
     488                 :            :  *   the results are undefined.
     489                 :            :  * @param n
     490                 :            :  *   The number of objects to add in the ring from the obj_table.
     491                 :            :  * @param free_space
     492                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     493                 :            :  *   enqueue operation has finished.
     494                 :            :  * @return
     495                 :            :  *   - n: Actual number of objects enqueued.
     496                 :            :  */
     497                 :            : static __rte_always_inline unsigned int
     498                 :       1108 : rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
     499                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     500                 :            : {
     501                 :       1108 :         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
     502                 :            :                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
     503                 :            : }
     504                 :            : 
     505                 :            : /**
     506                 :            :  * Enqueue several objects on a ring
     507                 :            :  *
     508                 :            :  * @warning This API is NOT multi-producers safe
     509                 :            :  *
     510                 :            :  * @param r
     511                 :            :  *   A pointer to the ring structure.
     512                 :            :  * @param obj_table
     513                 :            :  *   A pointer to a table of objects.
     514                 :            :  * @param esize
     515                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     516                 :            :  *   This must be the same value used while creating the ring. Otherwise
     517                 :            :  *   the results are undefined.
     518                 :            :  * @param n
     519                 :            :  *   The number of objects to add in the ring from the obj_table.
     520                 :            :  * @param free_space
     521                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     522                 :            :  *   enqueue operation has finished.
     523                 :            :  * @return
     524                 :            :  *   - n: Actual number of objects enqueued.
     525                 :            :  */
     526                 :            : static __rte_always_inline unsigned int
     527                 :       1108 : rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
     528                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     529                 :            : {
     530                 :       1108 :         return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
     531                 :            :                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
     532                 :            : }
     533                 :            : 
     534                 :            : /**
     535                 :            :  * Enqueue several objects on a ring.
     536                 :            :  *
     537                 :            :  * This function calls the multi-producer or the single-producer
     538                 :            :  * version depending on the default behavior that was specified at
     539                 :            :  * ring creation time (see flags).
     540                 :            :  *
     541                 :            :  * @param r
     542                 :            :  *   A pointer to the ring structure.
     543                 :            :  * @param obj_table
     544                 :            :  *   A pointer to a table of objects.
     545                 :            :  * @param esize
     546                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     547                 :            :  *   This must be the same value used while creating the ring. Otherwise
     548                 :            :  *   the results are undefined.
     549                 :            :  * @param n
     550                 :            :  *   The number of objects to add in the ring from the obj_table.
     551                 :            :  * @param free_space
     552                 :            :  *   if non-NULL, returns the amount of space in the ring after the
     553                 :            :  *   enqueue operation has finished.
     554                 :            :  * @return
     555                 :            :  *   - n: Actual number of objects enqueued.
     556                 :            :  */
     557                 :            : static __rte_always_inline unsigned int
     558                 :       3324 : rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
     559                 :            :                 unsigned int esize, unsigned int n, unsigned int *free_space)
     560                 :            : {
     561   [ -  +  -  -  :    6783956 :         switch (r->prod.sync_type) {
          -  -  +  -  -  
          -  +  +  +  +  
          -  +  +  +  +  
          -  -  +  -  -  
          -  -  +  -  -  
                      - ]
     562                 :            :         case RTE_RING_SYNC_MT:
     563                 :            :                 return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
     564                 :            :                         free_space);
     565                 :            :         case RTE_RING_SYNC_ST:
     566                 :            :                 return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
     567                 :            :                         free_space);
     568                 :            :         case RTE_RING_SYNC_MT_RTS:
     569                 :            :                 return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
     570                 :            :                         n, free_space);
     571                 :            :         case RTE_RING_SYNC_MT_HTS:
     572                 :            :                 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
     573                 :            :                         n, free_space);
     574                 :            :         }
     575                 :            : 
     576                 :            :         /* valid ring should never reach this point */
     577                 :            :         RTE_ASSERT(0);
     578   [ #  #  #  # ]:          0 :         if (free_space != NULL)
     579                 :          0 :                 *free_space = 0;
     580                 :            :         return 0;
     581                 :            : }
     582                 :            : 
     583                 :            : /**
     584                 :            :  * Dequeue several objects from a ring (multi-consumers safe). When the request
     585                 :            :  * objects are more than the available objects, only dequeue the actual number
     586                 :            :  * of objects
     587                 :            :  *
     588                 :            :  * This function uses a "compare and set" instruction to move the
     589                 :            :  * consumer index atomically.
     590                 :            :  *
     591                 :            :  * @param r
     592                 :            :  *   A pointer to the ring structure.
     593                 :            :  * @param obj_table
     594                 :            :  *   A pointer to a table of objects that will be filled.
     595                 :            :  * @param esize
     596                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     597                 :            :  *   This must be the same value used while creating the ring. Otherwise
     598                 :            :  *   the results are undefined.
     599                 :            :  * @param n
     600                 :            :  *   The number of objects to dequeue from the ring to the obj_table.
     601                 :            :  * @param available
     602                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     603                 :            :  *   dequeue has finished.
     604                 :            :  * @return
     605                 :            :  *   - n: Actual number of objects dequeued, 0 if ring is empty
     606                 :            :  */
     607                 :            : static __rte_always_inline unsigned int
     608                 :       1104 : rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
     609                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     610                 :            : {
     611                 :       1104 :         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
     612                 :            :                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
     613                 :            : }
     614                 :            : 
     615                 :            : /**
     616                 :            :  * Dequeue several objects from a ring (NOT multi-consumers safe).When the
     617                 :            :  * request objects are more than the available objects, only dequeue the
     618                 :            :  * actual number of objects
     619                 :            :  *
     620                 :            :  * @param r
     621                 :            :  *   A pointer to the ring structure.
     622                 :            :  * @param obj_table
     623                 :            :  *   A pointer to a table of objects that will be filled.
     624                 :            :  * @param esize
     625                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     626                 :            :  *   This must be the same value used while creating the ring. Otherwise
     627                 :            :  *   the results are undefined.
     628                 :            :  * @param n
     629                 :            :  *   The number of objects to dequeue from the ring to the obj_table.
     630                 :            :  * @param available
     631                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     632                 :            :  *   dequeue has finished.
     633                 :            :  * @return
     634                 :            :  *   - n: Actual number of objects dequeued, 0 if ring is empty
     635                 :            :  */
     636                 :            : static __rte_always_inline unsigned int
     637                 :       1104 : rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
     638                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     639                 :            : {
     640                 :       1104 :         return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
     641                 :            :                         RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
     642                 :            : }
     643                 :            : 
     644                 :            : /**
     645                 :            :  * Dequeue multiple objects from a ring up to a maximum number.
     646                 :            :  *
     647                 :            :  * This function calls the multi-consumers or the single-consumer
     648                 :            :  * version, depending on the default behaviour that was specified at
     649                 :            :  * ring creation time (see flags).
     650                 :            :  *
     651                 :            :  * @param r
     652                 :            :  *   A pointer to the ring structure.
     653                 :            :  * @param obj_table
     654                 :            :  *   A pointer to a table of objects that will be filled.
     655                 :            :  * @param esize
     656                 :            :  *   The size of ring element, in bytes. It must be a multiple of 4.
     657                 :            :  *   This must be the same value used while creating the ring. Otherwise
     658                 :            :  *   the results are undefined.
     659                 :            :  * @param n
     660                 :            :  *   The number of objects to dequeue from the ring to the obj_table.
     661                 :            :  * @param available
     662                 :            :  *   If non-NULL, returns the number of remaining ring entries after the
     663                 :            :  *   dequeue has finished.
     664                 :            :  * @return
     665                 :            :  *   - Number of objects dequeued
     666                 :            :  */
     667                 :            : static __rte_always_inline unsigned int
     668                 :       3312 : rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
     669                 :            :                 unsigned int esize, unsigned int n, unsigned int *available)
     670                 :            : {
     671   [ -  +  -  -  :   23587149 :         switch (r->cons.sync_type) {
          -  -  +  -  -  
          -  +  +  +  +  
          -  +  +  +  +  
                      - ]
     672                 :            :         case RTE_RING_SYNC_MT:
     673                 :            :                 return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
     674                 :            :                         available);
     675                 :            :         case RTE_RING_SYNC_ST:
     676                 :            :                 return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
     677                 :            :                         available);
     678                 :            :         case RTE_RING_SYNC_MT_RTS:
     679                 :            :                 return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
     680                 :            :                         n, available);
     681                 :            :         case RTE_RING_SYNC_MT_HTS:
     682                 :            :                 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
     683                 :            :                         n, available);
     684                 :            :         }
     685                 :            : 
     686                 :            :         /* valid ring should never reach this point */
     687                 :            :         RTE_ASSERT(0);
     688   [ #  #  #  # ]:          0 :         if (available != NULL)
     689                 :          0 :                 *available = 0;
     690                 :            :         return 0;
     691                 :            : }
     692                 :            : 
     693                 :            : #include <rte_ring_peek.h>
     694                 :            : #include <rte_ring_peek_zc.h>
     695                 :            : 
     696                 :            : #include <rte_ring.h>
     697                 :            : 
     698                 :            : #endif /* _RTE_RING_ELEM_H_ */

Generated by: LCOV version 1.14