Skip to content

SPSCQueue\

Lock-free, single-producer single-consumer ring buffer with power-of-two compile-time capacity.

template <typename T, std::size_t Capacity>
class SPSCQueue {
public:
  bool  push   (const T& item)          noexcept;      // copy
  bool  emplace(T&& item)               noexcept;      // move
  bool  try_emplace(auto&&... args);                  // in-place construct

  bool  pop    (T& out)                 noexcept;      // move into out
  T*    try_pop();                                     // raw pointer or nullptr
  std::optional<std::reference_wrapper<T>> try_pop_ref(); // non-owning ref

  void  clear() noexcept;                              // destroy all items
  bool  empty() const noexcept;
  bool  full()  const noexcept;
  size_t size() const noexcept;
};

Purpose

  • Provide a wait-free queue for producer/consumer pairs (e.g., EventBus publisher ↔ listener thread) with predictable latency and zero heap use.

Key Details

Aspect Detail
Capacity Must be a power of two; template parameter checked at compile time.
Cache lines _head, _tail, and buffer start each on separate 64-byte lines to avoid false sharing.
Exception safety Requires T to be nothrow destructible.
Destructor Drains remaining items, calling their destructors.

Producer Methods

  • push(const T&) — copy item.
  • emplace(T&&) — move item.
  • try_emplace(args…) — perfect-forward into placement-new.
    All three fail (return false) when the queue is full.

Consumer Methods

  • pop(T&) — move item into out, returns false if empty.
  • try_pop() — returns raw pointer to item or nullptr.
  • try_pop_ref() — returns std::optional<ref> for non-owning use.

Complexity

Operation Cost
Push/Pop O(1) atomic loads/stores, no locks.
Size O(1).

Typical Usage

SPSCQueue<Event*, 4096> q;
auto ok = q.try_emplace(evPtr);     // producer
...
if (auto* ev = q.try_pop()) { ... } // consumer

Notes

  • Single producer & single consumer only; undefined behaviour otherwise.
  • No dynamic memory: buffer is aligned_storage inside the queue object.