Lock-free circular buffer in C++ for fast & thread-safe telemetry
A circular buffer is a buffer with N-spaces, which can be thought of as being 'connected' as a circle, displaying similar properties to a double-ended queue. When items are pushed/written, the 'tail' index moves one position forward, and when items are popped/read, the 'head' index moves forward once. When the buffer has all spots occupied, it can no longer be pushed to without being popped from first. Because of using a write + read index, the occupied slots can be 'moved/slid around' the circle, not requiring the head element to be in the literal first index of the buffer. The head and tail can both be accessed as needed, making this type of structure efficient for specific use cases.
This particular C++ implementation makes use of several beneficial aspects of the language, including atomics for the read/write indexes, alignment specifications (alignas, alignof + paddings for vectorization/CPU cache access), type templating, rvalue references and move semantics rather than value copying. This makes this type of implementation great for cross-thread/concurrent usage in games, where we need to push game events on a main thread and access these events quickly and safely from a 2nd consumer thread (to drain game events to a socket or file for telemetry).
A class called MPSC is also included which uses the CircularBuffer class in a multi-threaded fashion, where each thread becomes a 'channel' to produce events on, getting its own circular buffer. A flush function combines events from all producer threads/channels and drains/writes each of them to a file (this can be changed to a socket or whatever else you like).
A brief example/test can be found in the main() function which shows usage of the CircularBuffer class on its own, along with the MPSC class using two threads, which drains their data to a file vals.txt.
Anyone is free to use the classes for whatever purpose, if there are any bugs I might be missing feel free to post an issue! Common topics which use this type of structure are within Quant trading, AV & AC telemetry, and lock-free event logging.