Ring buffer
A queue in a fixed block of memory where the read and write pointers chase each other round a circle.
The buffer is just an array; when a pointer reaches the end it wraps to the start. No allocation, no shuffling of data, constant time in and out. That makes it the default choice in firmware, where a UART interrupt drops characters in and the main loop takes them out at its own pace.
With exactly one producer and one consumer no lock is needed: the interrupt only touches the write index, the loop only the read index. Sizes are usually powers of two so the wrap is a cheap bitmask rather than a division. What remains is the eternal full-versus-empty ambiguity — both look like equal pointers — solved by sacrificing a slot or keeping a separate count. The same idea runs Linux network drivers, audio APIs and io_uring.