rte_seqlock.h(3)
π rte_seqlock.h β bestie, gather round π
okay so this page comes straight out of the Library Functions Manual (section 3, you know the vibe), and it's all about rte_seqlock.h β the header that gives you the RTE seqlock. no cap, this one's lowkey iconic. let's get into it π¦
β¨ NAME β¨
rte_seqlock.h β that's it. that's the name. short, sweet, main character energy. π
πΈ SYNOPSIS πΈ
first things first, you gotta pull in the friends:
#include <stdbool.h>
#include <stdint.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_seqcount.h>
#include <rte_spinlock.h>
π Data Structures
struct rte_seqlock_t
π Macros
#define RTE_SEQLOCK_INITIALIZER
π Functions
static void rte_seqlock_init (rte_seqlock_t *seqlock)
static uint32_t rte_seqlock_read_begin (const rte_seqlock_t *seqlock)
static bool rte_seqlock_read_retry (const rte_seqlock_t *seqlock,
uint32_t begin_sn)
static void rte_seqlock_write_lock (rte_seqlock_t *seqlock)
static void rte_seqlock_write_unlock (rte_seqlock_t *seqlock)
π Detailed Description π
RTE Seqlock β say it with me. β¨
A sequence lock (seqlock) is a synchronization primitive that lets multiple, parallel readers efficiently and safely (as in, in a data-race free manner, okay? no cheating) access lock-protected data. and the RTE seqlock permits multiple writers as well, because it's generous like that π«Ά. a spinlock is used for writer-writer synchronization.
A reader never blocks a writer. queen behavior. but heads up: very high frequency writes may prevent readers from making progress. π so like, don't spam.
A seqlock is not preemption-safe on the writer side. if a writer gets preempted, it may block readers until the writer thread is allowed to continue. so keep heavy computations out of the writer-side critical section, bestie β that delays readers and we don't do that here. π
Seqlocks are useful for data which are read by many cores, at a high frequency, and relatively infrequently written to. it's giving "everyone's reading, nobody's writing". π
One way to think about seqlocks is that they provide means to perform atomic operations on objects larger than what the native machine instructions allow for. β¨
To avoid resource reclamation issues, the data protected by a seqlock should typically be kept self-contained β e.g., no pointers to mutable, dynamically allocated data. no strays, no loose pointers, keep it tidy. π§
Example usage:
#define MAX_Y_LEN 16
// Application-defined example data structure, protected by a seqlock.
struct config {
rte_seqlock_t lock;
int param_x;
char param_y[MAX_Y_LEN];
};
// Accessor function for reading config fields.
void
config_read(const struct config *config, int *param_x, char *param_y)
{
uint32_t sn;
do {
sn = rte_seqlock_read_begin(&config->lock);
// Loads may be atomic or non-atomic, as in this example.
*param_x = config->param_x;
strcpy(param_y, config->param_y);
// An alternative to an immediate retry is to abort and
// try again at some later time, assuming progress is
// possible without the data.
} while (rte_seqlock_read_retry(&config->lock, sn));
}
// Accessor function for writing config fields.
void
config_update(struct config *config, int param_x, const char *param_y)
{
rte_seqlock_write_lock(&config->lock);
// Stores may be atomic or non-atomic, as in this example.
config->param_x = param_x;
strcpy(config->param_y, param_y);
rte_seqlock_write_unlock(&config->lock);
}
see how cute that loop is? the do { ... } while (rte_seqlock_read_retry(...)) is literally the whole trick. π
In case there is only a single writer, or writer-writer serialization is provided by other means, the use of sequence lock (i.e., rte_seqlock_t) can be replaced with the use of the "raw" rte_seqcount_t type instead. downgrade to raw mode, slay. π
See also
https://en.wikipedia.org/wiki/Seqlock.
Definition in file rte_seqlock.h.
β Macro Definition Documentation β
π #define RTE_SEQLOCK_INITIALIZER
Value:
{ \
.count = RTE_SEQCOUNT_INITIALIZER, \
.lock = RTE_SPINLOCK_INITIALIZER \
}
A static seqlock initializer. one macro, zero drama, everything pre-locked and ready. π«Ά
Definition at line 109 of file rte_seqlock.h.
π Function Documentation π
π void rte_seqlock_init (rte_seqlock_t * seqlock) [inline], [static]
Initialize the seqlock.
This function initializes the seqlock, and leaves the writer-side spinlock unlocked. (yes, unlocked. it's ready, not taken. π )
Parameters
seqlockβ A pointer to the seqlock.
Definition at line 125 of file rte_seqlock.h.
π uint32_t rte_seqlock_read_begin (const rte_seqlock_t * seqlock) [inline], [static]
Begin a read-side critical section.
See rte_seqcount_read_retry() for details.
Parameters
seqlockβ A pointer to the seqlock.
Returns
- The seqlock sequence number for this critical section, to later be passed to
rte_seqlock_read_retry().
See also
rte_seqlock_read_retry()rte_seqcount_read_retry()
Definition at line 146 of file rte_seqlock.h.
π bool rte_seqlock_read_retry (const rte_seqlock_t * seqlock, uint32_t begin_sn) [inline], [static]
End a read-side critical section.
See rte_seqcount_read_retry() for details.
Parameters
seqlockβ A pointer to the seqlock.begin_snβ The seqlock sequence number returned byrte_seqlock_read_begin().
Returns
trueorfalse, if the just-read seqlock-protected data was inconsistent or consistent, respectively, at the time it was read. sotrue= bestie the data was moving, run it back.false= you're good, it's consistent. π₯
See also
rte_seqlock_read_begin()
Definition at line 168 of file rte_seqlock.h.
π void rte_seqlock_write_lock (rte_seqlock_t * seqlock) [inline], [static]
Begin a write-side critical section.
A call to this function acquires the write lock associated seqlock, and marks the beginning of a write-side critical section.
After having called this function, the caller may go on to modify (both read and write) the protected data, in an atomic or non-atomic manner. do your thing. β¨
After the necessary updates have been performed, the application calls rte_seqlock_write_unlock().
This function is not preemption-safe in the sense that preemption of the calling thread may block reader progress until the writer thread is rescheduled. π
Unlike rte_seqlock_read_begin(), each call made to rte_seqlock_write_lock() must be matched with an unlock call. no ghost locks. every lock gets its unlock, periodt. π
Parameters
seqlockβ A pointer to the seqlock.
See also
rte_seqlock_write_unlock()
Definition at line 199 of file rte_seqlock.h.
π void rte_seqlock_write_unlock (rte_seqlock_t * seqlock) [inline], [static]
End a write-side critical section.
A call to this function marks the end of the write-side critical section, for seqlock. After this call has been made, the protected data may no longer be modified. hands off the data, bestie. π«
Parameters
seqlockβ A pointer to the seqlock.
See also
rte_seqlock_write_lock()
Definition at line 221 of file rte_seqlock.h.
π Author π
Generated automatically by Doxygen for DPDK from the source code. (not me writing this by hand at 2am, no ma'am, the robots did it π€β¨)
and that's the whole page, bestie!! you ate π no notes, fr fr. this was DPDK, Version 25.11.3, and we were all up in rte_seqlock.h(3) β go forth and seqlock responsibly. mwah. πππ¦
π¦ 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