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: 2024-01-22 15:55:54 Functions: 12 12 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 52 258 20.2 %

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

Generated by: LCOV version 1.14