Zephyr Project API 3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
spsc_lockfree.h File Reference

A lock-free and type safe power of 2 fixed sized single producer single consumer (SPSC) queue using a ringbuffer and atomics to ensure coherency. More...

#include <stdint.h>
#include <stdbool.h>
#include <zephyr/toolchain/common.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/util_macro.h>

Go to the source code of this file.

Macros

#define SPSC_INITIALIZER(sz, buf)
 Statically initialize an spsc.
 
#define SPSC_DECLARE(name, type)
 Declare an anonymous struct type for an spsc.
 
#define SPSC_DEFINE(name, type, sz)
 Define an spsc with a fixed size.
 
#define spsc_size(spsc)   ((spsc)->_spsc.mask + 1)
 Size of the SPSC queue.
 
#define spsc_reset(spsc)
 Initialize/reset a spsc such that its empty.
 
#define spsc_acquire(spsc)
 Acquire an element to produce from the SPSC.
 
#define spsc_produce(spsc)
 Produce one previously acquired element to the SPSC.
 
#define spsc_produce_all(spsc)
 Produce all previously acquired elements to the SPSC.
 
#define spsc_drop_all(spsc)
 Drop all previously acquired elements.
 
#define spsc_consume(spsc)
 Consume an element from the spsc.
 
#define spsc_release(spsc)
 Release a consumed element.
 
#define spsc_release_all(spsc)
 Release all consumed elements.
 
#define spsc_acquirable(spsc)    ({ (((spsc)->_spsc.in + (spsc)->_spsc.acquire) - (spsc)->_spsc.out) - spsc_size(spsc); })
 Count of acquirable in spsc.
 
#define spsc_consumable(spsc)   ({ (spsc)->_spsc.in - (spsc)->_spsc.out - (spsc)->_spsc.consume; })
 Count of consumables in spsc.
 
#define spsc_peek(spsc)
 Peek at the first available item in queue.
 
#define spsc_next(spsc, item)
 Peek at the next item in the queue from a given one.
 
#define spsc_prev(spsc, item)
 Get the previous item in the queue from a given one.
 

Detailed Description

A lock-free and type safe power of 2 fixed sized single producer single consumer (SPSC) queue using a ringbuffer and atomics to ensure coherency.

This SPSC queue implementation works on an array which wraps using a power of two size and uses a bit mask to perform a modulus. Atomics are used to allow single-producer single-consumer safe semantics without locks. Elements are expected to be of a fixed size. The API is type safe as the underlying buffer is typed and all usage is done through macros.

An SPSC queue may be declared on a stack or statically and work as intended so long as its lifetime outlives any usage. Static declarations should be the preferred method as stack . It is meant to be a shared object between two execution contexts (ISR and a thread for example)

An SPSC queue is safe to produce or consume in an ISR with O(1) push/pull.

Warning
SPSC is not safe to produce or consume in multiple execution contexts.

Safe usage would be, where A and B are unique execution contexts:

  1. ISR A producing and a Thread B consuming.
  2. Thread A producing and ISR B consuming.
  3. Thread A producing and Thread B consuming.
  4. ISR A producing and ISR B consuming.