Scroll to navigation

rte_seqlock.h(3) DPDK rte_seqlock.h(3)

NAME

rte_seqlock.h

SYNOPSIS

#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

A sequence lock (seqlock) is a synchronization primitive allowing multiple, parallel, readers to efficiently and safely (i.e., in a data-race free manner) access lock-protected data. The RTE seqlock permits multiple writers as well. A spinlock is used for writer-writer synchronization.

A reader never blocks a writer. Very high frequency writes may prevent readers from making progress.

A seqlock is not preemption-safe on the writer side. If a writer is preempted, it may block readers until the writer thread is allowed to continue. Heavy computations should be kept out of the writer-side critical section, to avoid delaying readers.

Seqlocks are useful for data which are read by many cores, at a high frequency, and relatively infrequently written to.

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).

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); }

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.

See also

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.

Definition at line 109 of file rte_seqlock.h.

Function Documentation

static 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.

Parameters

seqlock A pointer to the seqlock.

Definition at line 125 of file rte_seqlock.h.

static 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.

static 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 by rte_seqlock_read_begin().

Returns

true or false, if the just-read seqlock-protected data was inconsistent or consistent, respectively, at the time it was read.

See also

rte_seqlock_read_begin()

Definition at line 168 of file rte_seqlock.h.

static 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.

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.

Parameters

seqlock A pointer to the seqlock.

See also

rte_seqlock_write_unlock()

Definition at line 199 of file rte_seqlock.h.

static 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.

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.

Fri Dec 15 2023 Version 23.11.0