A single-producer, single-consumer (SPSC) ring buffer in C++, built as a step toward a lock-free version for low-latency, high-throughput packet processing in user space.
In progress (currently implementing a correct, mutex-based version as a baseline before replacing locks with atomics).
- Project scaffolding (CMake, build pipeline)
- Mutex + condition variable based ring buffer
- Lock-free version using
std::atomicwith acquire/release ordering - Packet ingestion (libpcap / raw sockets)
- Benchmarks: lock-free vs. mutex-based throughput and latency
Most "concurrent queue" tutorials stop at using a mutex. This project goes further: replacing the lock with atomic operations and explicit memory ordering, while staying correct — and measuring whether that effort actually pays off in throughput and latency compared to the naive lock-based version.
Requires CMake 3.16+ and a C++20 compiler.
cmake -B build
cmake --build buildRun the placeholder executables:
./build/packet_processor
./build/test_ring_buffer
./build/bench_ring_buffer(Filled in as the implementation progresses — see also NOTES.md for
day-to-day design decisions.)
- Fixed-capacity circular buffer, single producer / single consumer.
- Full/empty disambiguation via the "reserve one slot" technique: the
buffer is considered full when advancing
headby one would collide withtail, so onlyCapacity - 1slots are ever used at once.
- Current:
std::mutex+ twostd::condition_variables (one for "not full," one for "not empty") to avoid unnecessary wakeups. - Planned: replace the mutex with
std::atomic<size_t>head/tail indices, usingmemory_order_releaseon the writer side andmemory_order_acquireon the reader side.
(To be added once the lock-free version is implemented — throughput and latency compared against the mutex-based baseline.)
MIT