UBQ
UBQ is a lock-free, unbounded, multi-producer/multi-consumer (MPMC) queue built from a linked ring of fixed-size blocks, intended for concurrent producers and consumers.
Features
- Lock-free —
pushandpopnever park the calling thread. - Unbounded — capacity grows automatically as new blocks are allocated.
- MPMC — any number of producers and consumers may operate concurrently.
- Clonable handles — every
UBQ<T>clone shares the same underlying ring; reference counting frees the ring when the last clone is dropped. - FIFO ordering — elements are returned in the order they were pushed, within each block.
Usage
Add UBQ to your Cargo.toml:
[]
= "2"
Basic example
use UBQ;
Multi-threaded (MPMC)
use UBQ;
use thread;
let q: = UBQnew;
// Spawn 4 producers and 4 consumers.
let m = 100_000;
let handles: =
.flat_map
.collect;
for h in handles
See the full API reference on docs.rs.
How it works
UBQ organises elements into fixed-size blocks linked in a circular ring. Two atomic head pointers — phead and chead — track which block is currently accepting pushes and which is being drained by consumers.
Within each block, a pair of packed counters distinguishes claimed from committed slots. A consumer spin-waits briefly on a stability predicate before claiming a slot, ensuring it reads only fully-committed writes. When a block is exhausted the last claimer atomically advances the head pointer to the next block, recycling the old one once it has been fully consumed.
The correctness of the protocol rests on six invariants ([C1]–[C6])
documented inline in the source.
Benchmarks
This repo includes a benchmark harness that compares UBQ against other unbounded queues in SPSC, MPSC, SPMC, and MPMC scenarios. Results are emitted as JSON; an optional helper script generates throughput bar plots.
Run the default benchmark suite (release mode):
Limit to specific queues or scenarios:
Generate plots (PNG) and CSVs:
Block size variants
UBQ's block size is controlled at compile time via feature flags. To layer multiple block sizes on the same plot:
# Base comparison (all queues, default block size).
# UBQ-only runs with alternative block sizes.
# Combined plot with all three sizes overlaid.
Loom model checking
UBQ includes opt-in loom tests for deterministic interleaving exploration of high-contention block-boundary scenarios:
LOOM_MAX_PREEMPTIONS=3
By default, the scenario runner caps model exploration at 200 permutations for
practical runtime; override with LOOM_MAX_PERMUTATIONS.
License
MIT