199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * 399a2dd95SBruce Richardson * Copyright (c) 2019 Arm Limited 499a2dd95SBruce Richardson * Copyright (c) 2010-2017 Intel Corporation 599a2dd95SBruce Richardson * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org 699a2dd95SBruce Richardson * All rights reserved. 799a2dd95SBruce Richardson * Derived from FreeBSD's bufring.h 899a2dd95SBruce Richardson * Used as BSD-3 Licensed with permission from Kip Macy. 999a2dd95SBruce Richardson */ 1099a2dd95SBruce Richardson 1199a2dd95SBruce Richardson #ifndef _RTE_RING_ELEM_H_ 1299a2dd95SBruce Richardson #define _RTE_RING_ELEM_H_ 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson /** 1599a2dd95SBruce Richardson * @file 1699a2dd95SBruce Richardson * RTE Ring with user defined element size 1799a2dd95SBruce Richardson */ 1899a2dd95SBruce Richardson 1999a2dd95SBruce Richardson #include <rte_ring_core.h> 2099a2dd95SBruce Richardson #include <rte_ring_elem_pvt.h> 2199a2dd95SBruce Richardson 2299a2dd95SBruce Richardson /** 2399a2dd95SBruce Richardson * Calculate the memory size needed for a ring with given element size 2499a2dd95SBruce Richardson * 2599a2dd95SBruce Richardson * This function returns the number of bytes needed for a ring, given 2699a2dd95SBruce Richardson * the number of elements in it and the size of the element. This value 2799a2dd95SBruce Richardson * is the sum of the size of the structure rte_ring and the size of the 2899a2dd95SBruce Richardson * memory needed for storing the elements. The value is aligned to a cache 2999a2dd95SBruce Richardson * line size. 3099a2dd95SBruce Richardson * 3199a2dd95SBruce Richardson * @param esize 3299a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 3399a2dd95SBruce Richardson * @param count 3499a2dd95SBruce Richardson * The number of elements in the ring (must be a power of 2). 3599a2dd95SBruce Richardson * @return 3699a2dd95SBruce Richardson * - The memory size needed for the ring on success. 3799a2dd95SBruce Richardson * - -EINVAL - esize is not a multiple of 4 or count provided is not a 3899a2dd95SBruce Richardson * power of 2. 3999a2dd95SBruce Richardson */ 4099a2dd95SBruce Richardson ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count); 4199a2dd95SBruce Richardson 4299a2dd95SBruce Richardson /** 4399a2dd95SBruce Richardson * Create a new ring named *name* that stores elements with given size. 4499a2dd95SBruce Richardson * 4599a2dd95SBruce Richardson * This function uses ``memzone_reserve()`` to allocate memory. Then it 4699a2dd95SBruce Richardson * calls rte_ring_init() to initialize an empty ring. 4799a2dd95SBruce Richardson * 4899a2dd95SBruce Richardson * The new ring size is set to *count*, which must be a power of 4999a2dd95SBruce Richardson * two. Water marking is disabled by default. The real usable ring size 50*436e82b7SRobert Sanford * is *count-1* instead of *count* to differentiate a full ring from an 5199a2dd95SBruce Richardson * empty ring. 5299a2dd95SBruce Richardson * 5399a2dd95SBruce Richardson * The ring is added in RTE_TAILQ_RING list. 5499a2dd95SBruce Richardson * 5599a2dd95SBruce Richardson * @param name 5699a2dd95SBruce Richardson * The name of the ring. 5799a2dd95SBruce Richardson * @param esize 5899a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 5999a2dd95SBruce Richardson * @param count 6099a2dd95SBruce Richardson * The number of elements in the ring (must be a power of 2). 6199a2dd95SBruce Richardson * @param socket_id 6299a2dd95SBruce Richardson * The *socket_id* argument is the socket identifier in case of 6399a2dd95SBruce Richardson * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA 6499a2dd95SBruce Richardson * constraint for the reserved zone. 6599a2dd95SBruce Richardson * @param flags 6699a2dd95SBruce Richardson * An OR of the following: 6799a2dd95SBruce Richardson * - One of mutually exclusive flags that define producer behavior: 6899a2dd95SBruce Richardson * - RING_F_SP_ENQ: If this flag is set, the default behavior when 6999a2dd95SBruce Richardson * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 7099a2dd95SBruce Richardson * is "single-producer". 7199a2dd95SBruce Richardson * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when 7299a2dd95SBruce Richardson * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 7399a2dd95SBruce Richardson * is "multi-producer RTS mode". 7499a2dd95SBruce Richardson * - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when 7599a2dd95SBruce Richardson * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()`` 7699a2dd95SBruce Richardson * is "multi-producer HTS mode". 7799a2dd95SBruce Richardson * If none of these flags is set, then default "multi-producer" 7899a2dd95SBruce Richardson * behavior is selected. 7999a2dd95SBruce Richardson * - One of mutually exclusive flags that define consumer behavior: 8099a2dd95SBruce Richardson * - RING_F_SC_DEQ: If this flag is set, the default behavior when 8199a2dd95SBruce Richardson * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 8299a2dd95SBruce Richardson * is "single-consumer". Otherwise, it is "multi-consumers". 8399a2dd95SBruce Richardson * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when 8499a2dd95SBruce Richardson * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 8599a2dd95SBruce Richardson * is "multi-consumer RTS mode". 8699a2dd95SBruce Richardson * - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when 8799a2dd95SBruce Richardson * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()`` 8899a2dd95SBruce Richardson * is "multi-consumer HTS mode". 8999a2dd95SBruce Richardson * If none of these flags is set, then default "multi-consumer" 9099a2dd95SBruce Richardson * behavior is selected. 9199a2dd95SBruce Richardson * @return 9299a2dd95SBruce Richardson * On success, the pointer to the new allocated ring. NULL on error with 9399a2dd95SBruce Richardson * rte_errno set appropriately. Possible errno values include: 9499a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 9599a2dd95SBruce Richardson * - EINVAL - esize is not a multiple of 4 or count provided is not a 9699a2dd95SBruce Richardson * power of 2. 9799a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 9899a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 9999a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 10099a2dd95SBruce Richardson */ 10199a2dd95SBruce Richardson struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize, 10299a2dd95SBruce Richardson unsigned int count, int socket_id, unsigned int flags); 10399a2dd95SBruce Richardson 10499a2dd95SBruce Richardson /** 10599a2dd95SBruce Richardson * Enqueue several objects on the ring (multi-producers safe). 10699a2dd95SBruce Richardson * 10799a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 10899a2dd95SBruce Richardson * producer index atomically. 10999a2dd95SBruce Richardson * 11099a2dd95SBruce Richardson * @param r 11199a2dd95SBruce Richardson * A pointer to the ring structure. 11299a2dd95SBruce Richardson * @param obj_table 11399a2dd95SBruce Richardson * A pointer to a table of objects. 11499a2dd95SBruce Richardson * @param esize 11599a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 11699a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 11799a2dd95SBruce Richardson * the results are undefined. 11899a2dd95SBruce Richardson * @param n 11999a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 12099a2dd95SBruce Richardson * @param free_space 12199a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 12299a2dd95SBruce Richardson * enqueue operation has finished. 12399a2dd95SBruce Richardson * @return 12499a2dd95SBruce Richardson * The number of objects enqueued, either 0 or n 12599a2dd95SBruce Richardson */ 12699a2dd95SBruce Richardson static __rte_always_inline unsigned int 12799a2dd95SBruce Richardson rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, 12899a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 12999a2dd95SBruce Richardson { 13099a2dd95SBruce Richardson return __rte_ring_do_enqueue_elem(r, obj_table, esize, n, 13199a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space); 13299a2dd95SBruce Richardson } 13399a2dd95SBruce Richardson 13499a2dd95SBruce Richardson /** 13599a2dd95SBruce Richardson * Enqueue several objects on a ring 13699a2dd95SBruce Richardson * 13799a2dd95SBruce Richardson * @warning This API is NOT multi-producers safe 13899a2dd95SBruce Richardson * 13999a2dd95SBruce Richardson * @param r 14099a2dd95SBruce Richardson * A pointer to the ring structure. 14199a2dd95SBruce Richardson * @param obj_table 14299a2dd95SBruce Richardson * A pointer to a table of objects. 14399a2dd95SBruce Richardson * @param esize 14499a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 14599a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 14699a2dd95SBruce Richardson * the results are undefined. 14799a2dd95SBruce Richardson * @param n 14899a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 14999a2dd95SBruce Richardson * @param free_space 15099a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 15199a2dd95SBruce Richardson * enqueue operation has finished. 15299a2dd95SBruce Richardson * @return 15399a2dd95SBruce Richardson * The number of objects enqueued, either 0 or n 15499a2dd95SBruce Richardson */ 15599a2dd95SBruce Richardson static __rte_always_inline unsigned int 15699a2dd95SBruce Richardson rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, 15799a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 15899a2dd95SBruce Richardson { 15999a2dd95SBruce Richardson return __rte_ring_do_enqueue_elem(r, obj_table, esize, n, 16099a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space); 16199a2dd95SBruce Richardson } 16299a2dd95SBruce Richardson 16399a2dd95SBruce Richardson #include <rte_ring_hts.h> 16499a2dd95SBruce Richardson #include <rte_ring_rts.h> 16599a2dd95SBruce Richardson 16699a2dd95SBruce Richardson /** 16799a2dd95SBruce Richardson * Enqueue several objects on a ring. 16899a2dd95SBruce Richardson * 16999a2dd95SBruce Richardson * This function calls the multi-producer or the single-producer 17099a2dd95SBruce Richardson * version depending on the default behavior that was specified at 17199a2dd95SBruce Richardson * ring creation time (see flags). 17299a2dd95SBruce Richardson * 17399a2dd95SBruce Richardson * @param r 17499a2dd95SBruce Richardson * A pointer to the ring structure. 17599a2dd95SBruce Richardson * @param obj_table 17699a2dd95SBruce Richardson * A pointer to a table of objects. 17799a2dd95SBruce Richardson * @param esize 17899a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 17999a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 18099a2dd95SBruce Richardson * the results are undefined. 18199a2dd95SBruce Richardson * @param n 18299a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 18399a2dd95SBruce Richardson * @param free_space 18499a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 18599a2dd95SBruce Richardson * enqueue operation has finished. 18699a2dd95SBruce Richardson * @return 18799a2dd95SBruce Richardson * The number of objects enqueued, either 0 or n 18899a2dd95SBruce Richardson */ 18999a2dd95SBruce Richardson static __rte_always_inline unsigned int 19099a2dd95SBruce Richardson rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, 19199a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 19299a2dd95SBruce Richardson { 19399a2dd95SBruce Richardson switch (r->prod.sync_type) { 19499a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 19599a2dd95SBruce Richardson return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n, 19699a2dd95SBruce Richardson free_space); 19799a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 19899a2dd95SBruce Richardson return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n, 19999a2dd95SBruce Richardson free_space); 20099a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 20199a2dd95SBruce Richardson return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n, 20299a2dd95SBruce Richardson free_space); 20399a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 20499a2dd95SBruce Richardson return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n, 20599a2dd95SBruce Richardson free_space); 20699a2dd95SBruce Richardson } 20799a2dd95SBruce Richardson 20899a2dd95SBruce Richardson /* valid ring should never reach this point */ 20999a2dd95SBruce Richardson RTE_ASSERT(0); 21099a2dd95SBruce Richardson if (free_space != NULL) 21199a2dd95SBruce Richardson *free_space = 0; 21299a2dd95SBruce Richardson return 0; 21399a2dd95SBruce Richardson } 21499a2dd95SBruce Richardson 21599a2dd95SBruce Richardson /** 21699a2dd95SBruce Richardson * Enqueue one object on a ring (multi-producers safe). 21799a2dd95SBruce Richardson * 21899a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 21999a2dd95SBruce Richardson * producer index atomically. 22099a2dd95SBruce Richardson * 22199a2dd95SBruce Richardson * @param r 22299a2dd95SBruce Richardson * A pointer to the ring structure. 22399a2dd95SBruce Richardson * @param obj 22499a2dd95SBruce Richardson * A pointer to the object to be added. 22599a2dd95SBruce Richardson * @param esize 22699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 22799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 22899a2dd95SBruce Richardson * the results are undefined. 22999a2dd95SBruce Richardson * @return 23099a2dd95SBruce Richardson * - 0: Success; objects enqueued. 23199a2dd95SBruce Richardson * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued. 23299a2dd95SBruce Richardson */ 23399a2dd95SBruce Richardson static __rte_always_inline int 23499a2dd95SBruce Richardson rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize) 23599a2dd95SBruce Richardson { 23699a2dd95SBruce Richardson return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 : 23799a2dd95SBruce Richardson -ENOBUFS; 23899a2dd95SBruce Richardson } 23999a2dd95SBruce Richardson 24099a2dd95SBruce Richardson /** 24199a2dd95SBruce Richardson * Enqueue one object on a ring 24299a2dd95SBruce Richardson * 24399a2dd95SBruce Richardson * @warning This API is NOT multi-producers safe 24499a2dd95SBruce Richardson * 24599a2dd95SBruce Richardson * @param r 24699a2dd95SBruce Richardson * A pointer to the ring structure. 24799a2dd95SBruce Richardson * @param obj 24899a2dd95SBruce Richardson * A pointer to the object to be added. 24999a2dd95SBruce Richardson * @param esize 25099a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 25199a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 25299a2dd95SBruce Richardson * the results are undefined. 25399a2dd95SBruce Richardson * @return 25499a2dd95SBruce Richardson * - 0: Success; objects enqueued. 25599a2dd95SBruce Richardson * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued. 25699a2dd95SBruce Richardson */ 25799a2dd95SBruce Richardson static __rte_always_inline int 25899a2dd95SBruce Richardson rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize) 25999a2dd95SBruce Richardson { 26099a2dd95SBruce Richardson return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 : 26199a2dd95SBruce Richardson -ENOBUFS; 26299a2dd95SBruce Richardson } 26399a2dd95SBruce Richardson 26499a2dd95SBruce Richardson /** 26599a2dd95SBruce Richardson * Enqueue one object on a ring. 26699a2dd95SBruce Richardson * 26799a2dd95SBruce Richardson * This function calls the multi-producer or the single-producer 26899a2dd95SBruce Richardson * version, depending on the default behaviour that was specified at 26999a2dd95SBruce Richardson * ring creation time (see flags). 27099a2dd95SBruce Richardson * 27199a2dd95SBruce Richardson * @param r 27299a2dd95SBruce Richardson * A pointer to the ring structure. 27399a2dd95SBruce Richardson * @param obj 27499a2dd95SBruce Richardson * A pointer to the object to be added. 27599a2dd95SBruce Richardson * @param esize 27699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 27799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 27899a2dd95SBruce Richardson * the results are undefined. 27999a2dd95SBruce Richardson * @return 28099a2dd95SBruce Richardson * - 0: Success; objects enqueued. 28199a2dd95SBruce Richardson * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued. 28299a2dd95SBruce Richardson */ 28399a2dd95SBruce Richardson static __rte_always_inline int 28499a2dd95SBruce Richardson rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize) 28599a2dd95SBruce Richardson { 28699a2dd95SBruce Richardson return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 : 28799a2dd95SBruce Richardson -ENOBUFS; 28899a2dd95SBruce Richardson } 28999a2dd95SBruce Richardson 29099a2dd95SBruce Richardson /** 29199a2dd95SBruce Richardson * Dequeue several objects from a ring (multi-consumers safe). 29299a2dd95SBruce Richardson * 29399a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 29499a2dd95SBruce Richardson * consumer index atomically. 29599a2dd95SBruce Richardson * 29699a2dd95SBruce Richardson * @param r 29799a2dd95SBruce Richardson * A pointer to the ring structure. 29899a2dd95SBruce Richardson * @param obj_table 29999a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 30099a2dd95SBruce Richardson * @param esize 30199a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 30299a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 30399a2dd95SBruce Richardson * the results are undefined. 30499a2dd95SBruce Richardson * @param n 30599a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table. 30699a2dd95SBruce Richardson * @param available 30799a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 30899a2dd95SBruce Richardson * dequeue has finished. 30999a2dd95SBruce Richardson * @return 31099a2dd95SBruce Richardson * The number of objects dequeued, either 0 or n 31199a2dd95SBruce Richardson */ 31299a2dd95SBruce Richardson static __rte_always_inline unsigned int 31399a2dd95SBruce Richardson rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, 31499a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 31599a2dd95SBruce Richardson { 31699a2dd95SBruce Richardson return __rte_ring_do_dequeue_elem(r, obj_table, esize, n, 31799a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available); 31899a2dd95SBruce Richardson } 31999a2dd95SBruce Richardson 32099a2dd95SBruce Richardson /** 32199a2dd95SBruce Richardson * Dequeue several objects from a ring (NOT multi-consumers safe). 32299a2dd95SBruce Richardson * 32399a2dd95SBruce Richardson * @param r 32499a2dd95SBruce Richardson * A pointer to the ring structure. 32599a2dd95SBruce Richardson * @param obj_table 32699a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 32799a2dd95SBruce Richardson * @param esize 32899a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 32999a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 33099a2dd95SBruce Richardson * the results are undefined. 33199a2dd95SBruce Richardson * @param n 33299a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table, 33399a2dd95SBruce Richardson * must be strictly positive. 33499a2dd95SBruce Richardson * @param available 33599a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 33699a2dd95SBruce Richardson * dequeue has finished. 33799a2dd95SBruce Richardson * @return 33899a2dd95SBruce Richardson * The number of objects dequeued, either 0 or n 33999a2dd95SBruce Richardson */ 34099a2dd95SBruce Richardson static __rte_always_inline unsigned int 34199a2dd95SBruce Richardson rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, 34299a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 34399a2dd95SBruce Richardson { 34499a2dd95SBruce Richardson return __rte_ring_do_dequeue_elem(r, obj_table, esize, n, 34599a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available); 34699a2dd95SBruce Richardson } 34799a2dd95SBruce Richardson 34899a2dd95SBruce Richardson /** 34999a2dd95SBruce Richardson * Dequeue several objects from a ring. 35099a2dd95SBruce Richardson * 35199a2dd95SBruce Richardson * This function calls the multi-consumers or the single-consumer 35299a2dd95SBruce Richardson * version, depending on the default behaviour that was specified at 35399a2dd95SBruce Richardson * ring creation time (see flags). 35499a2dd95SBruce Richardson * 35599a2dd95SBruce Richardson * @param r 35699a2dd95SBruce Richardson * A pointer to the ring structure. 35799a2dd95SBruce Richardson * @param obj_table 35899a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 35999a2dd95SBruce Richardson * @param esize 36099a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 36199a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 36299a2dd95SBruce Richardson * the results are undefined. 36399a2dd95SBruce Richardson * @param n 36499a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table. 36599a2dd95SBruce Richardson * @param available 36699a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 36799a2dd95SBruce Richardson * dequeue has finished. 36899a2dd95SBruce Richardson * @return 36999a2dd95SBruce Richardson * The number of objects dequeued, either 0 or n 37099a2dd95SBruce Richardson */ 37199a2dd95SBruce Richardson static __rte_always_inline unsigned int 37299a2dd95SBruce Richardson rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, 37399a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 37499a2dd95SBruce Richardson { 37599a2dd95SBruce Richardson switch (r->cons.sync_type) { 37699a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 37799a2dd95SBruce Richardson return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n, 37899a2dd95SBruce Richardson available); 37999a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 38099a2dd95SBruce Richardson return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n, 38199a2dd95SBruce Richardson available); 38299a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 38399a2dd95SBruce Richardson return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize, 38499a2dd95SBruce Richardson n, available); 38599a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 38699a2dd95SBruce Richardson return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize, 38799a2dd95SBruce Richardson n, available); 38899a2dd95SBruce Richardson } 38999a2dd95SBruce Richardson 39099a2dd95SBruce Richardson /* valid ring should never reach this point */ 39199a2dd95SBruce Richardson RTE_ASSERT(0); 39299a2dd95SBruce Richardson if (available != NULL) 39399a2dd95SBruce Richardson *available = 0; 39499a2dd95SBruce Richardson return 0; 39599a2dd95SBruce Richardson } 39699a2dd95SBruce Richardson 39799a2dd95SBruce Richardson /** 39899a2dd95SBruce Richardson * Dequeue one object from a ring (multi-consumers safe). 39999a2dd95SBruce Richardson * 40099a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 40199a2dd95SBruce Richardson * consumer index atomically. 40299a2dd95SBruce Richardson * 40399a2dd95SBruce Richardson * @param r 40499a2dd95SBruce Richardson * A pointer to the ring structure. 40599a2dd95SBruce Richardson * @param obj_p 40699a2dd95SBruce Richardson * A pointer to the object that will be filled. 40799a2dd95SBruce Richardson * @param esize 40899a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 40999a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 41099a2dd95SBruce Richardson * the results are undefined. 41199a2dd95SBruce Richardson * @return 41299a2dd95SBruce Richardson * - 0: Success; objects dequeued. 41399a2dd95SBruce Richardson * - -ENOENT: Not enough entries in the ring to dequeue; no object is 41499a2dd95SBruce Richardson * dequeued. 41599a2dd95SBruce Richardson */ 41699a2dd95SBruce Richardson static __rte_always_inline int 41799a2dd95SBruce Richardson rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p, 41899a2dd95SBruce Richardson unsigned int esize) 41999a2dd95SBruce Richardson { 42099a2dd95SBruce Richardson return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 : 42199a2dd95SBruce Richardson -ENOENT; 42299a2dd95SBruce Richardson } 42399a2dd95SBruce Richardson 42499a2dd95SBruce Richardson /** 42599a2dd95SBruce Richardson * Dequeue one object from a ring (NOT multi-consumers safe). 42699a2dd95SBruce Richardson * 42799a2dd95SBruce Richardson * @param r 42899a2dd95SBruce Richardson * A pointer to the ring structure. 42999a2dd95SBruce Richardson * @param obj_p 43099a2dd95SBruce Richardson * A pointer to the object that will be filled. 43199a2dd95SBruce Richardson * @param esize 43299a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 43399a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 43499a2dd95SBruce Richardson * the results are undefined. 43599a2dd95SBruce Richardson * @return 43699a2dd95SBruce Richardson * - 0: Success; objects dequeued. 43799a2dd95SBruce Richardson * - -ENOENT: Not enough entries in the ring to dequeue, no object is 43899a2dd95SBruce Richardson * dequeued. 43999a2dd95SBruce Richardson */ 44099a2dd95SBruce Richardson static __rte_always_inline int 44199a2dd95SBruce Richardson rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p, 44299a2dd95SBruce Richardson unsigned int esize) 44399a2dd95SBruce Richardson { 44499a2dd95SBruce Richardson return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 : 44599a2dd95SBruce Richardson -ENOENT; 44699a2dd95SBruce Richardson } 44799a2dd95SBruce Richardson 44899a2dd95SBruce Richardson /** 44999a2dd95SBruce Richardson * Dequeue one object from a ring. 45099a2dd95SBruce Richardson * 45199a2dd95SBruce Richardson * This function calls the multi-consumers or the single-consumer 45299a2dd95SBruce Richardson * version depending on the default behaviour that was specified at 45399a2dd95SBruce Richardson * ring creation time (see flags). 45499a2dd95SBruce Richardson * 45599a2dd95SBruce Richardson * @param r 45699a2dd95SBruce Richardson * A pointer to the ring structure. 45799a2dd95SBruce Richardson * @param obj_p 45899a2dd95SBruce Richardson * A pointer to the object that will be filled. 45999a2dd95SBruce Richardson * @param esize 46099a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 46199a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 46299a2dd95SBruce Richardson * the results are undefined. 46399a2dd95SBruce Richardson * @return 46499a2dd95SBruce Richardson * - 0: Success, objects dequeued. 46599a2dd95SBruce Richardson * - -ENOENT: Not enough entries in the ring to dequeue, no object is 46699a2dd95SBruce Richardson * dequeued. 46799a2dd95SBruce Richardson */ 46899a2dd95SBruce Richardson static __rte_always_inline int 46999a2dd95SBruce Richardson rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize) 47099a2dd95SBruce Richardson { 47199a2dd95SBruce Richardson return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 : 47299a2dd95SBruce Richardson -ENOENT; 47399a2dd95SBruce Richardson } 47499a2dd95SBruce Richardson 47599a2dd95SBruce Richardson /** 47699a2dd95SBruce Richardson * Enqueue several objects on the ring (multi-producers safe). 47799a2dd95SBruce Richardson * 47899a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 47999a2dd95SBruce Richardson * producer index atomically. 48099a2dd95SBruce Richardson * 48199a2dd95SBruce Richardson * @param r 48299a2dd95SBruce Richardson * A pointer to the ring structure. 48399a2dd95SBruce Richardson * @param obj_table 48499a2dd95SBruce Richardson * A pointer to a table of objects. 48599a2dd95SBruce Richardson * @param esize 48699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 48799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 48899a2dd95SBruce Richardson * the results are undefined. 48999a2dd95SBruce Richardson * @param n 49099a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 49199a2dd95SBruce Richardson * @param free_space 49299a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 49399a2dd95SBruce Richardson * enqueue operation has finished. 49499a2dd95SBruce Richardson * @return 49599a2dd95SBruce Richardson * - n: Actual number of objects enqueued. 49699a2dd95SBruce Richardson */ 49799a2dd95SBruce Richardson static __rte_always_inline unsigned int 49899a2dd95SBruce Richardson rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, 49999a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 50099a2dd95SBruce Richardson { 50199a2dd95SBruce Richardson return __rte_ring_do_enqueue_elem(r, obj_table, esize, n, 50299a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space); 50399a2dd95SBruce Richardson } 50499a2dd95SBruce Richardson 50599a2dd95SBruce Richardson /** 50699a2dd95SBruce Richardson * Enqueue several objects on a ring 50799a2dd95SBruce Richardson * 50899a2dd95SBruce Richardson * @warning This API is NOT multi-producers safe 50999a2dd95SBruce Richardson * 51099a2dd95SBruce Richardson * @param r 51199a2dd95SBruce Richardson * A pointer to the ring structure. 51299a2dd95SBruce Richardson * @param obj_table 51399a2dd95SBruce Richardson * A pointer to a table of objects. 51499a2dd95SBruce Richardson * @param esize 51599a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 51699a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 51799a2dd95SBruce Richardson * the results are undefined. 51899a2dd95SBruce Richardson * @param n 51999a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 52099a2dd95SBruce Richardson * @param free_space 52199a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 52299a2dd95SBruce Richardson * enqueue operation has finished. 52399a2dd95SBruce Richardson * @return 52499a2dd95SBruce Richardson * - n: Actual number of objects enqueued. 52599a2dd95SBruce Richardson */ 52699a2dd95SBruce Richardson static __rte_always_inline unsigned int 52799a2dd95SBruce Richardson rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, 52899a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 52999a2dd95SBruce Richardson { 53099a2dd95SBruce Richardson return __rte_ring_do_enqueue_elem(r, obj_table, esize, n, 53199a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space); 53299a2dd95SBruce Richardson } 53399a2dd95SBruce Richardson 53499a2dd95SBruce Richardson /** 53599a2dd95SBruce Richardson * Enqueue several objects on a ring. 53699a2dd95SBruce Richardson * 53799a2dd95SBruce Richardson * This function calls the multi-producer or the single-producer 53899a2dd95SBruce Richardson * version depending on the default behavior that was specified at 53999a2dd95SBruce Richardson * ring creation time (see flags). 54099a2dd95SBruce Richardson * 54199a2dd95SBruce Richardson * @param r 54299a2dd95SBruce Richardson * A pointer to the ring structure. 54399a2dd95SBruce Richardson * @param obj_table 54499a2dd95SBruce Richardson * A pointer to a table of objects. 54599a2dd95SBruce Richardson * @param esize 54699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 54799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 54899a2dd95SBruce Richardson * the results are undefined. 54999a2dd95SBruce Richardson * @param n 55099a2dd95SBruce Richardson * The number of objects to add in the ring from the obj_table. 55199a2dd95SBruce Richardson * @param free_space 55299a2dd95SBruce Richardson * if non-NULL, returns the amount of space in the ring after the 55399a2dd95SBruce Richardson * enqueue operation has finished. 55499a2dd95SBruce Richardson * @return 55599a2dd95SBruce Richardson * - n: Actual number of objects enqueued. 55699a2dd95SBruce Richardson */ 55799a2dd95SBruce Richardson static __rte_always_inline unsigned int 55899a2dd95SBruce Richardson rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, 55999a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *free_space) 56099a2dd95SBruce Richardson { 56199a2dd95SBruce Richardson switch (r->prod.sync_type) { 56299a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 56399a2dd95SBruce Richardson return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n, 56499a2dd95SBruce Richardson free_space); 56599a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 56699a2dd95SBruce Richardson return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n, 56799a2dd95SBruce Richardson free_space); 56899a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 56999a2dd95SBruce Richardson return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize, 57099a2dd95SBruce Richardson n, free_space); 57199a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 57299a2dd95SBruce Richardson return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize, 57399a2dd95SBruce Richardson n, free_space); 57499a2dd95SBruce Richardson } 57599a2dd95SBruce Richardson 57699a2dd95SBruce Richardson /* valid ring should never reach this point */ 57799a2dd95SBruce Richardson RTE_ASSERT(0); 57899a2dd95SBruce Richardson if (free_space != NULL) 57999a2dd95SBruce Richardson *free_space = 0; 58099a2dd95SBruce Richardson return 0; 58199a2dd95SBruce Richardson } 58299a2dd95SBruce Richardson 58399a2dd95SBruce Richardson /** 58499a2dd95SBruce Richardson * Dequeue several objects from a ring (multi-consumers safe). When the request 58599a2dd95SBruce Richardson * objects are more than the available objects, only dequeue the actual number 58699a2dd95SBruce Richardson * of objects 58799a2dd95SBruce Richardson * 58899a2dd95SBruce Richardson * This function uses a "compare and set" instruction to move the 58999a2dd95SBruce Richardson * consumer index atomically. 59099a2dd95SBruce Richardson * 59199a2dd95SBruce Richardson * @param r 59299a2dd95SBruce Richardson * A pointer to the ring structure. 59399a2dd95SBruce Richardson * @param obj_table 59499a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 59599a2dd95SBruce Richardson * @param esize 59699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 59799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 59899a2dd95SBruce Richardson * the results are undefined. 59999a2dd95SBruce Richardson * @param n 60099a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table. 60199a2dd95SBruce Richardson * @param available 60299a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 60399a2dd95SBruce Richardson * dequeue has finished. 60499a2dd95SBruce Richardson * @return 60599a2dd95SBruce Richardson * - n: Actual number of objects dequeued, 0 if ring is empty 60699a2dd95SBruce Richardson */ 60799a2dd95SBruce Richardson static __rte_always_inline unsigned int 60899a2dd95SBruce Richardson rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table, 60999a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 61099a2dd95SBruce Richardson { 61199a2dd95SBruce Richardson return __rte_ring_do_dequeue_elem(r, obj_table, esize, n, 61299a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available); 61399a2dd95SBruce Richardson } 61499a2dd95SBruce Richardson 61599a2dd95SBruce Richardson /** 61699a2dd95SBruce Richardson * Dequeue several objects from a ring (NOT multi-consumers safe).When the 61799a2dd95SBruce Richardson * request objects are more than the available objects, only dequeue the 61899a2dd95SBruce Richardson * actual number of objects 61999a2dd95SBruce Richardson * 62099a2dd95SBruce Richardson * @param r 62199a2dd95SBruce Richardson * A pointer to the ring structure. 62299a2dd95SBruce Richardson * @param obj_table 62399a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 62499a2dd95SBruce Richardson * @param esize 62599a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 62699a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 62799a2dd95SBruce Richardson * the results are undefined. 62899a2dd95SBruce Richardson * @param n 62999a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table. 63099a2dd95SBruce Richardson * @param available 63199a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 63299a2dd95SBruce Richardson * dequeue has finished. 63399a2dd95SBruce Richardson * @return 63499a2dd95SBruce Richardson * - n: Actual number of objects dequeued, 0 if ring is empty 63599a2dd95SBruce Richardson */ 63699a2dd95SBruce Richardson static __rte_always_inline unsigned int 63799a2dd95SBruce Richardson rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table, 63899a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 63999a2dd95SBruce Richardson { 64099a2dd95SBruce Richardson return __rte_ring_do_dequeue_elem(r, obj_table, esize, n, 64199a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available); 64299a2dd95SBruce Richardson } 64399a2dd95SBruce Richardson 64499a2dd95SBruce Richardson /** 64599a2dd95SBruce Richardson * Dequeue multiple objects from a ring up to a maximum number. 64699a2dd95SBruce Richardson * 64799a2dd95SBruce Richardson * This function calls the multi-consumers or the single-consumer 64899a2dd95SBruce Richardson * version, depending on the default behaviour that was specified at 64999a2dd95SBruce Richardson * ring creation time (see flags). 65099a2dd95SBruce Richardson * 65199a2dd95SBruce Richardson * @param r 65299a2dd95SBruce Richardson * A pointer to the ring structure. 65399a2dd95SBruce Richardson * @param obj_table 65499a2dd95SBruce Richardson * A pointer to a table of objects that will be filled. 65599a2dd95SBruce Richardson * @param esize 65699a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 65799a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 65899a2dd95SBruce Richardson * the results are undefined. 65999a2dd95SBruce Richardson * @param n 66099a2dd95SBruce Richardson * The number of objects to dequeue from the ring to the obj_table. 66199a2dd95SBruce Richardson * @param available 66299a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 66399a2dd95SBruce Richardson * dequeue has finished. 66499a2dd95SBruce Richardson * @return 66599a2dd95SBruce Richardson * - Number of objects dequeued 66699a2dd95SBruce Richardson */ 66799a2dd95SBruce Richardson static __rte_always_inline unsigned int 66899a2dd95SBruce Richardson rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table, 66999a2dd95SBruce Richardson unsigned int esize, unsigned int n, unsigned int *available) 67099a2dd95SBruce Richardson { 67199a2dd95SBruce Richardson switch (r->cons.sync_type) { 67299a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 67399a2dd95SBruce Richardson return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n, 67499a2dd95SBruce Richardson available); 67599a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 67699a2dd95SBruce Richardson return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n, 67799a2dd95SBruce Richardson available); 67899a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 67999a2dd95SBruce Richardson return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize, 68099a2dd95SBruce Richardson n, available); 68199a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 68299a2dd95SBruce Richardson return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize, 68399a2dd95SBruce Richardson n, available); 68499a2dd95SBruce Richardson } 68599a2dd95SBruce Richardson 68699a2dd95SBruce Richardson /* valid ring should never reach this point */ 68799a2dd95SBruce Richardson RTE_ASSERT(0); 68899a2dd95SBruce Richardson if (available != NULL) 68999a2dd95SBruce Richardson *available = 0; 69099a2dd95SBruce Richardson return 0; 69199a2dd95SBruce Richardson } 69299a2dd95SBruce Richardson 69399a2dd95SBruce Richardson #include <rte_ring_peek.h> 69499a2dd95SBruce Richardson #include <rte_ring_peek_zc.h> 69599a2dd95SBruce Richardson 69699a2dd95SBruce Richardson #include <rte_ring.h> 69799a2dd95SBruce Richardson 69899a2dd95SBruce Richardson #endif /* _RTE_RING_ELEM_H_ */ 699