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, no esize in 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, no esize argument:
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-side HTD_MAX:
static uint32_t rte_ring_get_prod_htd_max (const struct rte_ring *r)
  • rte_ring_set_prod_htd_max โ€” set the producer-side HTD_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-side HTD_MAX:
static uint32_t rte_ring_get_cons_htd_max (const struct rte_ring *r)
  • rte_ring_set_cons_htd_max โ€” set the consumer-side HTD_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.cnt for each head.value update
  • write head.value and head.cnt atomically (64-bit CAS) ๐Ÿ”ฅ
  • move tail.value ahead only when tail.cnt + 1 == head.cnt (indicating that this is the last thread updating the tail) ๐Ÿ‘‘
  • increment tail.cnt when each enqueue/dequeue op finishes (no matter if tail.value going to change or not)
  • write tail.value and tail.cnt atomically (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 changing head.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 == 0 we'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 of 4. 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 the esize. ๐Ÿ˜ญ
  • n โ€” the number of objects to add in the ring from the obj_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 of 4. 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 the obj_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 of 4. 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 the obj_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 of 4. 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 the obj_table.
  • available โ€” if non-NULL, returns the number of remaining ring entries after the dequeue has finished.

Returns

  • n: actual number of objects dequeued, 0 if 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 of void * pointers (objects).
  • n โ€” the number of objects to add in the ring from the obj_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 of void * pointers (objects) that will be filled.
  • n โ€” the number of objects to dequeue from the ring to the obj_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 of void * pointers (objects).
  • n โ€” the number of objects to add in the ring from the obj_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 of void * pointers (objects) that will be filled.
  • n โ€” the number of objects to dequeue from the ring to the obj_table.
  • available โ€” if non-NULL, returns the number of remaining ring entries after the dequeue has finished.

Returns

  • n: actual number of objects dequeued, 0 if 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