Developer knowledge network ยท moderated exchange

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Knowledge indexLive
4Categories
919Threads
2.8KPosts
Tutorial

Writing a Lock-Free Single-Producer Single-Consumer (SPSC) Queue in C++20

ptr_arithmetic
C++ Wizard
MEMBER
Rep: 162
Join Date: May 2018
Posts: 73
Thanks: 42
1 months ago ยท Jul 6, 2026 4:22 AM
#1

For high-frequency IPC between memory reader thread and ImGui render thread:

CPP
template <typename T, size_t Capacity>
class SPSCQueue {
    static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of 2");
    T m_buffer[Capacity];
    alignas(64) std::atomic<size_t> m_head{0}; // Cache line aligned to prevent false sharing
    alignas(64) std::atomic<size_t> m_tail{0};
public:
    bool Push(const T& item) {
        const size_t tail = m_tail.load(std::memory_order_relaxed);
        if ((tail - m_head.load(std::memory_order_acquire)) == Capacity) return false; // Full
        m_buffer[tail & (Capacity - 1)] = item;
        m_tail.store(tail + 1, std::memory_order_release);
        return true;
    }
    bool Pop(T& item) {
        const size_t head = m_head.load(std::memory_order_relaxed);
        if (head == m_tail.load(std::memory_order_acquire)) return false; // Empty
        item = m_buffer[head & (Capacity - 1)];
        m_head.store(head + 1, std::memory_order_release);
        return true;
    }
};

Zero mutex contention, sub-10 nanosecond enqueue latency!

vtable_slayer
Senior Reverser
MEMBER
Rep: 215
Join Date: Mar 2018
Posts: 86
Thanks: 61
1 months ago ยท Jul 6, 2026 6:51 AM
#2

alignas(64) cache line alignment on head and tail prevents L1 cache invalidation ping-pong between CPU cores. Brilliant implementation.

sig_scanner_sam
Pattern Master
MEMBER
Rep: 210
Join Date: Dec 2019
Posts: 11
Thanks: 51
1 months ago ยท Jul 6, 2026 4:58 PM
#3

Benchmark: 120 million push/pop ops per second on Ryzen 7800X3D.