rte_ring_rts.h(3)
๐ NAME ๐
rte_ring_rts.h โ yes bestie, that's the whole name, and yes, this is the section 3 manual page for it (rte_ring_rts.h(3), for the citation girlies). โจ
It's the header that brings you Relaxed Tail Sync (RTS) ring mode. Buckle up. ๐ฆ
๐ฆ SYNOPSIS ๐ฆ
#include <rte_ring_rts_elem_pvt.h>
๐ Functions
rte_ring_mp_rts_enqueue_bulk_elemโ the element-size flavored, multi-producer bulk enqueue:
static __rte_always_inline unsigned int
rte_ring_mp_rts_enqueue_bulk_elem (struct rte_ring *r, const void
*obj_table, unsigned int esize, unsigned int n, unsigned int
*free_space)
rte_ring_mc_rts_dequeue_bulk_elemโ same energy, but dequeue, and multi-consumer:
static __rte_always_inline unsigned int
rte_ring_mc_rts_dequeue_bulk_elem (struct rte_ring *r, void
*obj_table, unsigned int esize, unsigned int n, unsigned int
*available)
rte_ring_mp_rts_enqueue_burst_elemโ the burst girlie, element-size edition, enqueue side:
static __rte_always_inline unsigned int
rte_ring_mp_rts_enqueue_burst_elem (struct rte_ring *r, const void
*obj_table, unsigned int esize, unsigned int n, unsigned int
*free_space)
rte_ring_mc_rts_dequeue_burst_elemโ burst dequeue, element-size, multi-consumer:
static __rte_always_inline unsigned int
rte_ring_mc_rts_dequeue_burst_elem (struct rte_ring *r, void
*obj_table, unsigned int esize, unsigned int n, unsigned int
*available)
rte_ring_mp_rts_enqueue_bulkโ bulk enqueue, noesizein sight (these ones just don't take one, periodt):
static __rte_always_inline unsigned int rte_ring_mp_rts_enqueue_bulk
(struct rte_ring *r, void *const *obj_table, unsigned int n,
unsigned int *free_space)
rte_ring_mc_rts_dequeue_bulkโ bulk dequeue,esize-free version:
static __rte_always_inline unsigned int rte_ring_mc_rts_dequeue_bulk
(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int
*available)
rte_ring_mp_rts_enqueue_burstโ burst enqueue, and again, noesizeargument:
static __rte_always_inline unsigned int rte_ring_mp_rts_enqueue_burst
(struct rte_ring *r, void *const *obj_table, unsigned int n,
unsigned int *free_space)
rte_ring_mc_rts_dequeue_burstโ burst dequeue,esize-free:
static __rte_always_inline unsigned int rte_ring_mc_rts_dequeue_burst
(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int
*available)
rte_ring_get_prod_htd_maxโ peek at the producer-sideHTD_MAX:
static uint32_t rte_ring_get_prod_htd_max (const struct rte_ring *r)
rte_ring_set_prod_htd_maxโ set the producer-sideHTD_MAX:
static int rte_ring_set_prod_htd_max (struct rte_ring *r, uint32_t v)
rte_ring_get_cons_htd_maxโ peek at the consumer-sideHTD_MAX:
static uint32_t rte_ring_get_cons_htd_max (const struct rte_ring *r)
rte_ring_set_cons_htd_maxโ set the consumer-sideHTD_MAX:
static int rte_ring_set_cons_htd_max (struct rte_ring *r, uint32_t v)
๐ DETAILED DESCRIPTION ๐
๐จ OK SO REAL TALK FIRST: it is not recommended to include this file directly. Please include <rte_ring.h> instead. Like, do not come for this file directly, go through the front door, bestie. ๐ซถ
So what even is in here? Functions for Relaxed Tail Sync (RTS) ring mode. ๐ธ
The main idea stays the same as for our original MP/MC synchronization mechanism. The main difference โ and this is the iconic part โ is that the tail value is not increased by every thread that finished enqueue/dequeue. It's increased by only the current last one doing enqueue/dequeue. ๐ That lets threads skip spinning on the tail value, and leaves the actual tail value change to that last thread at a given instance.
RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation: one for the head update, second for the tail update. And as a gain? It lets the thread avoid spinning/waiting on the tail value. In comparison, the original MP/MC algorithm requires one 32-bit CAS for the head update and waiting/spinning on the tail value. Trade-offs, they exist. ๐
โจ Brief outline โจ
- introduce update counter (
cnt) for both head and tail. ๐งฎ - increment
head.cntfor eachhead.valueupdate - write
head.valueandhead.cntatomically (64-bit CAS) ๐ฅ - move
tail.valueahead only whentail.cnt + 1 == head.cnt(indicating that this is the last thread updating the tail) ๐ - increment
tail.cntwhen each enqueue/dequeue op finishes (no matter iftail.valuegoing to change or not) - write
tail.valueandtail.cntatomically (64-bit CAS) ๐ฅ
๐ To avoid producer/consumer starvation ๐
- limit max allowed distance between head and tail value (
HTD_MAX). I.E. thread is allowed to proceed with changinghead.value, only when:head.value - tail.value <= HTD_MAX
HTD_MAX is an optional parameter. Let's break that down, because the numbers matter:
- With
HTD_MAX == 0we'll have a fully serialized ring โ i.e. only one thread at a time will be able to enqueue/dequeue to/from the ring. ๐ญ One. Thread. At a time. - With
HTD_MAX >= ring.capacityโ no limitation. ๐ - By default
HTD_MAX == ring.capacity / 8.
Definition in file rte_ring_rts.h. ๐
๐ Function Documentation ๐
Bestie, this is the whole roster โ every single RTS ring function, no skips, no "you can read the rest later" nonsense. Buckle in. ๐
๐ธ rte_ring_mp_rts_enqueue_bulk_elem()
__rte_always_inline unsigned int rte_ring_mp_rts_enqueue_bulk_elem (struct rte_ring * r, const void * obj_table, unsigned int esize, unsigned int n, unsigned int * free_space) [static]
Slaps a whole batch of objects onto the RTS ring, and it's multi-producers safe โ so yes, multiple producers can do this at the same time without things getting messy. ๐
Parameters
rโ a pointer to the ring structure. The ring.obj_tableโ a pointer to a table of objects.esizeโ the size of ring element, in bytes. It must be a multiple of4. And it has to be the exact same value you used while creating the ring โ otherwise the results are undefined. Not "a little off", undefined. Respect theesize. ๐ญnโ the number of objects to add in the ring from theobj_table.free_spaceโ if non-NULL, returns the amount of space in the ring after the enqueue operation has finished.
Returns
The number of objects enqueued, either 0 or n.
Definition at line 80 of file rte_ring_rts.h.
๐ฆ rte_ring_mc_rts_dequeue_bulk_elem()
__rte_always_inline unsigned int rte_ring_mc_rts_dequeue_bulk_elem (struct rte_ring * r, void * obj_table, unsigned int esize, unsigned int n, unsigned int * available) [static]
Takes a whole batch of objects off an RTS ring, and it's multi-consumers safe. Everyone eats. ๐
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table of objects that will be filled.esizeโ the size of ring element, in bytes. It must be a multiple of4. It must be the same value used while creating the ring โ otherwise the results are undefined. Periodt.nโ the number of objects to dequeue from the ring to theobj_table.availableโ if non-NULL, returns the number of remaining ring entries after the dequeue has finished.
Returns
The number of objects dequeued, either 0 or n.
Definition at line 107 of file rte_ring_rts.h.
โจ rte_ring_mp_rts_enqueue_burst_elem()
__rte_always_inline unsigned int rte_ring_mp_rts_enqueue_burst_elem (struct rte_ring * r, const void * obj_table, unsigned int esize, unsigned int n, unsigned int * free_space) [static]
Same energy as the bulk version: several objects onto the RTS ring, multi-producers safe. ๐
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table of objects.esizeโ the size of ring element, in bytes. It must be a multiple of4. This must be the same value used while creating the ring โ otherwise the results are undefined.nโ the number of objects to add in the ring from theobj_table.free_spaceโ if non-NULL, returns the amount of space in the ring after the enqueue operation has finished.
Returns
n: actual number of objects enqueued.
Definition at line 134 of file rte_ring_rts.h.
๐ rte_ring_mc_rts_dequeue_burst_elem()
__rte_always_inline unsigned int rte_ring_mc_rts_dequeue_burst_elem (struct rte_ring * r, void * obj_table, unsigned int esize, unsigned int n, unsigned int * available) [static]
Dequeues several objects from an RTS ring, multi-consumers safe. And here's the lil twist: when the requested objects are more than the available objects, it only dequeues the actual number of objects. It's giving "we work with what we have." ๐
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table of objects that will be filled.esizeโ the size of ring element, in bytes. It must be a multiple of4. This must be the same value used while creating the ring โ otherwise the results are undefined.nโ the number of objects to dequeue from the ring to theobj_table.availableโ if non-NULL, returns the number of remaining ring entries after the dequeue has finished.
Returns
n: actual number of objects dequeued,0if ring is empty.
Definition at line 163 of file rte_ring_rts.h.
๐ rte_ring_mp_rts_enqueue_bulk()
__rte_always_inline unsigned int rte_ring_mp_rts_enqueue_bulk (struct rte_ring * r, void *const * obj_table, unsigned int n, unsigned int * free_space) [static]
Enqueue several objects on the RTS ring, multi-producers safe. Same vibe as the _elem one but for plain void * pointers. ๐ซถ
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table ofvoid *pointers (objects).nโ the number of objects to add in the ring from theobj_table.free_spaceโ if non-NULL, returns the amount of space in the ring after the enqueue operation has finished.
Returns
The number of objects enqueued, either 0 or n.
Definition at line 186 of file rte_ring_rts.h.
๐ง rte_ring_mc_rts_dequeue_bulk()
__rte_always_inline unsigned int rte_ring_mc_rts_dequeue_bulk (struct rte_ring * r, void ** obj_table, unsigned int n, unsigned int * available) [static]
Dequeue several objects from an RTS ring, multi-consumers safe.
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table ofvoid *pointers (objects) that will be filled.nโ the number of objects to dequeue from the ring to theobj_table.availableโ if non-NULL, returns the number of remaining ring entries after the dequeue has finished.
Returns
The number of objects dequeued, either 0 or n.
Definition at line 209 of file rte_ring_rts.h.
โญ rte_ring_mp_rts_enqueue_burst()
__rte_always_inline unsigned int rte_ring_mp_rts_enqueue_burst (struct rte_ring * r, void *const * obj_table, unsigned int n, unsigned int * free_space) [static]
Enqueue several objects on the RTS ring, multi-producers safe. Burst edition. ๐ฅ
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table ofvoid *pointers (objects).nโ the number of objects to add in the ring from theobj_table.free_spaceโ if non-NULL, returns the amount of space in the ring after the enqueue operation has finished.
Returns
n: actual number of objects enqueued.
Definition at line 232 of file rte_ring_rts.h.
๐ rte_ring_mc_rts_dequeue_burst()
__rte_always_inline unsigned int rte_ring_mc_rts_dequeue_burst (struct rte_ring * r, void ** obj_table, unsigned int n, unsigned int * available) [static]
Dequeue several objects from an RTS ring, multi-consumers safe. When the requested objects are more than the available objects, only dequeue the actual number of objects. No you don't get to ask for more than exists, bestie. ๐
Parameters
rโ a pointer to the ring structure.obj_tableโ a pointer to a table ofvoid *pointers (objects) that will be filled.nโ the number of objects to dequeue from the ring to theobj_table.availableโ if non-NULL, returns the number of remaining ring entries after the dequeue has finished.
Returns
n: actual number of objects dequeued,0if ring is empty.
Definition at line 257 of file rte_ring_rts.h.
๐ rte_ring_get_prod_htd_max()
uint32_t rte_ring_get_prod_htd_max (const struct rte_ring * r) [inline], [static]
Returns the producer max Head-Tail-Distance (HTD). Yes, HTD, we're fancy here. ๐
Parameters
rโ a pointer to the ring structure.
Returns
Producer HTD value, if producer is set in appropriate sync mode, or UINT32_MAX otherwise.
Definition at line 274 of file rte_ring_rts.h.
๐ rte_ring_set_prod_htd_max()
int rte_ring_set_prod_htd_max (struct rte_ring * r, uint32_t v) [inline], [static]
Sets the producer max Head-Tail-Distance (HTD). Note that the producer has to use the appropriate sync mode (RTS). Don't skip that part. ๐ค
Parameters
rโ a pointer to the ring structure.vโ new HTD value to setup.
Returns
Zero on success, or negative error code otherwise.
Definition at line 293 of file rte_ring_rts.h.
๐ธ rte_ring_get_cons_htd_max()
uint32_t rte_ring_get_cons_htd_max (const struct rte_ring * r) [inline], [static]
Returns the consumer max Head-Tail-Distance (HTD). The other half of the HTD duo. ๐
Parameters
rโ a pointer to the ring structure.
Returns
Consumer HTD value, if consumer is set in appropriate sync mode, or UINT32_MAX otherwise.
Definition at line 312 of file rte_ring_rts.h.
๐ rte_ring_set_cons_htd_max()
int rte_ring_set_cons_htd_max (struct rte_ring * r, uint32_t v) [inline], [static]
Sets the consumer max Head-Tail-Distance (HTD). Note that the consumer has to use the appropriate sync mode (RTS). Same rule as the producer one, no shortcuts. ๐
Parameters
rโ a pointer to the ring structure.vโ new HTD value to setup.
Returns
Zero on success, or negative error code otherwise.
Definition at line 331 of file rte_ring_rts.h.
๐ Author ๐
Generated automatically by Doxygen for DPDK from the source code. Not me, not you โ Doxygen did that. Respect. ๐ซถ
And that's the whole page, bestie โ rte_ring_rts.h(3) from DPDK Version 25.11.3. Go forth and enqueue responsibly. ๐ โจ๐
๐ฆ where this page comes from
- ubuntu resolute: dpdk-doc 25.11.3-0ubuntu0.26.04.1 ยท BSD-3-Clause
- ubuntu stonking: dpdk-doc 25.11.3-1 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms