VLink  2.0.0
A high-performance communication middleware
mpmc_queue.h File Reference

Bounded lock-free multi-producer multi-consumer ring buffer with optional cv blocking. More...

#include <array>
#include <atomic>
#include <chrono>
#include <cstddef>
#include <limits>
#include <memory>
#include <mutex>
#include <new>
#include <utility>
#include "./condition_variable.h"
#include "./macros.h"
#include "./utils.h"
Include dependency graph for mpmc_queue.h:

Go to the source code of this file.

Classes

class  vlink::MpmcQueueBase
 Non-template base class that owns every element-type-independent piece of state. More...
 
struct  vlink::MpmcQueueBase::QuitFlag
 
class  vlink::MpmcQueue< T >
 Fixed-capacity lock-free MPMC ring buffer over T. More...
 

Namespaces

 

Macros

#define VLINK_NO_INSTRUMENT
 

Detailed Description

Bounded lock-free multi-producer multi-consumer ring buffer with optional cv blocking.

MpmcQueue is a fixed-capacity ring buffer based on a turn-counter algorithm. Each slot holds a per-slot atomic turn counter that encodes whether the slot is currently empty (ready for a producer) or full (ready for a consumer).

Algorithm summary
  • Producers atomically increment head_ to claim a slot and spin until chunk.turn == turn(head) * 2 (slot empty), then construct the value and publish turn = turn(head) * 2 + 1 (slot full).
  • Consumers atomically increment tail_ to claim a slot and spin until chunk.turn == turn(tail) * 2 + 1 (slot full), then move the value out and publish turn = turn(tail) * 2 + 2 (slot empty for next round).
  • Spinning runs for kFirstSpinTimes (32) iterations before calling yield_cpu.
  • The struct is cache-line aligned: head_, tail_ and each Chunk live in dedicated 64-byte regions to avoid false sharing.
Producer / consumer guarantees
Behaviour Push contract Pop contract
kNoBehavior No notification on success or failure Spin-wait only
kConditionBehavior Acquire cv_mtx_, notify not_empty Wake not_full waiter on pop
Blocking variants emplace / push spin until success pop spins until a slot is full
Non-blocking variants try_emplace / try_push return on full try_pop returns false on empty
Quit signal notify_to_quit drops further pushes Pop returns without value once quit set
Example
// Producer:
// Consumer:
int val = 0;
Note
emplace / pop block by spinning; for bounded producers prefer the try_* forms. Capacity must be >= 1 (otherwise std::invalid_argument is thrown). notify_to_quit gracefully drains pending waiters and silently drops further pushes.

Macro Definition Documentation

◆ VLINK_NO_INSTRUMENT

#define VLINK_NO_INSTRUMENT