#pragma once #include "IrInterruptGuard.h" template class RingBuffer { public: RingBuffer() : start(0), end(0) {} bool isFull() const { return ((end + 1) % BufferSize) == start; } bool isEmpty() const { return start == end; } bool push(T element) { bool pushed = false; IrInterruptGuard guard; if (!isFull()) { data[end] = element; end = (end + 1) % BufferSize; pushed = true; } return pushed; } T* pop() { IrInterruptGuard guard; T* value = nullptr; if (!isEmpty()) { value = &data[start]; start = (start + 1) % BufferSize; } return value; } // B5: безопасный pop — копирует элемент под ОДНОЙ критсекцией и отдаёт по значению. // (T* pop() отдаёт указатель во внутренний слот; после выхода слот снова может быть перезаписан.) bool pop(T &out) { bool popped = false; IrInterruptGuard guard; if (!isEmpty()) { out = data[start]; start = (start + 1) % BufferSize; popped = true; } return popped; } private: T data[BufferSize]; unsigned int start, end; };