numam-dpdk/lib/ring/rte_ring_hts.h
Sean Morrissey f01eff0d23 ring: promote new sync modes and peek to stable
These methods were introduced in 20.05.
There has been no changes in their public API since then.
They seem mature enough to remove the experimental tag.

Signed-off-by: Sean Morrissey <sean.morrissey@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2021-10-05 10:09:15 +02:00

242 lines
7.8 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
* Used as BSD-3 Licensed with permission from Kip Macy.
*/
#ifndef _RTE_RING_HTS_H_
#define _RTE_RING_HTS_H_
/**
* @file rte_ring_hts.h
* It is not recommended to include this file directly.
* Please include <rte_ring.h> instead.
*
* Contains functions for serialized, aka Head-Tail Sync (HTS) ring mode.
* In that mode enqueue/dequeue operation is fully serialized:
* at any given moment only one enqueue/dequeue operation can proceed.
* This is achieved by allowing a thread to proceed with changing head.value
* only when head.value == tail.value.
* Both head and tail values are updated atomically (as one 64-bit value).
* To achieve that 64-bit CAS is used by head update routine.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_ring_hts_elem_pvt.h>
/**
* Enqueue several objects on the HTS ring (multi-producers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of objects.
* @param esize
* The size of ring element, in bytes. It must be a multiple of 4.
* This must be the same value used while creating the ring. Otherwise
* the results are undefined.
* @param n
* The number of objects to add in the ring from the obj_table.
* @param free_space
* if non-NULL, returns the amount of space in the ring after the
* enqueue operation has finished.
* @return
* The number of objects enqueued, either 0 or n
*/
static __rte_always_inline unsigned int
rte_ring_mp_hts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_hts_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, free_space);
}
/**
* Dequeue several objects from an HTS ring (multi-consumers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of objects that will be filled.
* @param esize
* The size of ring element, in bytes. It must be a multiple of 4.
* This must be the same value used while creating the ring. Otherwise
* the results are undefined.
* @param n
* The number of objects to dequeue from the ring to the obj_table.
* @param available
* If non-NULL, returns the number of remaining ring entries after the
* dequeue has finished.
* @return
* The number of objects dequeued, either 0 or n
*/
static __rte_always_inline unsigned int
rte_ring_mc_hts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_hts_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, available);
}
/**
* Enqueue several objects on the HTS ring (multi-producers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of objects.
* @param esize
* The size of ring element, in bytes. It must be a multiple of 4.
* This must be the same value used while creating the ring. Otherwise
* the results are undefined.
* @param n
* The number of objects to add in the ring from the obj_table.
* @param free_space
* if non-NULL, returns the amount of space in the ring after the
* enqueue operation has finished.
* @return
* - n: Actual number of objects enqueued.
*/
static __rte_always_inline unsigned int
rte_ring_mp_hts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_hts_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE, free_space);
}
/**
* Dequeue several objects from an HTS ring (multi-consumers safe).
* When the requested objects are more than the available objects,
* only dequeue the actual number of objects.
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of objects that will be filled.
* @param esize
* The size of ring element, in bytes. It must be a multiple of 4.
* This must be the same value used while creating the ring. Otherwise
* the results are undefined.
* @param n
* The number of objects to dequeue from the ring to the obj_table.
* @param available
* If non-NULL, returns the number of remaining ring entries after the
* dequeue has finished.
* @return
* - n: Actual number of objects dequeued, 0 if ring is empty
*/
static __rte_always_inline unsigned int
rte_ring_mc_hts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_hts_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE, available);
}
/**
* Enqueue several objects on the HTS ring (multi-producers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of void * pointers (objects).
* @param n
* The number of objects to add in the ring from the obj_table.
* @param free_space
* if non-NULL, returns the amount of space in the ring after the
* enqueue operation has finished.
* @return
* The number of objects enqueued, either 0 or n
*/
static __rte_always_inline unsigned int
rte_ring_mp_hts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table,
sizeof(uintptr_t), n, free_space);
}
/**
* Dequeue several objects from an HTS ring (multi-consumers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of void * pointers (objects) that will be filled.
* @param n
* The number of objects to dequeue from the ring to the obj_table.
* @param available
* If non-NULL, returns the number of remaining ring entries after the
* dequeue has finished.
* @return
* The number of objects dequeued, either 0 or n
*/
static __rte_always_inline unsigned int
rte_ring_mc_hts_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table,
sizeof(uintptr_t), n, available);
}
/**
* Enqueue several objects on the HTS ring (multi-producers safe).
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of void * pointers (objects).
* @param n
* The number of objects to add in the ring from the obj_table.
* @param free_space
* if non-NULL, returns the amount of space in the ring after the
* enqueue operation has finished.
* @return
* - n: Actual number of objects enqueued.
*/
static __rte_always_inline unsigned int
rte_ring_mp_hts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table,
sizeof(uintptr_t), n, free_space);
}
/**
* Dequeue several objects from an HTS ring (multi-consumers safe).
* When the requested objects are more than the available objects,
* only dequeue the actual number of objects.
*
* @param r
* A pointer to the ring structure.
* @param obj_table
* A pointer to a table of void * pointers (objects) that will be filled.
* @param n
* The number of objects to dequeue from the ring to the obj_table.
* @param available
* If non-NULL, returns the number of remaining ring entries after the
* dequeue has finished.
* @return
* - n: Actual number of objects dequeued, 0 if ring is empty
*/
static __rte_always_inline unsigned int
rte_ring_mc_hts_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table,
sizeof(uintptr_t), n, available);
}
#ifdef __cplusplus
}
#endif
#endif /* _RTE_RING_HTS_H_ */