diff --git a/include/ring.hpp b/include/ring.hpp index 8c0bf69..902114a 100644 --- a/include/ring.hpp +++ b/include/ring.hpp @@ -21,6 +21,11 @@ #include #include +/** + * @brief A generic ring buffer implementation with thread safety. + * + * @tparam T Type of the data stored in the buffer. + */ template class RingBuffer { @@ -34,6 +39,13 @@ private: size_t Tail; public: + /** + * @brief Construct a new RingBuffer object. + * + * Initializes the buffer and the spin lock. The default buffer size is 16. + * + * @param Size Initial size (capacity) of the buffer. + */ RingBuffer(size_t Size = 16) : Lock(new spin_lock()), Buffer(new T[Size]), @@ -42,18 +54,33 @@ public: Head(0), Tail(0) {} + /** + * @brief Destroy the RingBuffer object. + * + * Releases the allocated memory for the buffer and the spin lock. + */ ~RingBuffer() { delete Lock; delete[] Buffer; } - size_t Write(const T *Data, size_t Size) + /** + * @brief Write data to the ring buffer. + * + * Writes up to `nReads` elements from `Data` into the buffer. If the buffer + * is full, the function stops writing. + * + * @param Data Pointer to the data to be written. + * @param nReads Number of elements to write. + * @return size_t Number of elements actually written. + */ + size_t Write(const T *Data, size_t nReads) { sl_guard(*Lock); size_t written = 0; - while (Size > 0) + while (nReads > 0) { if (BufferCount == BufferSize) break; @@ -62,18 +89,28 @@ public: Head = (Head + 1) % BufferSize; BufferCount++; written++; - Size--; + nReads--; } return written; } - size_t Read(T *Data, size_t Size) + /** + * @brief Read data from the ring buffer. + * + * Reads up to `nReads` elements from the buffer into `Data`. If the buffer + * is empty, the function stops reading. + * + * @param Data Pointer to the memory where read elements will be stored. + * @param nReads Number of elements to read. + * @return size_t Number of elements actually read. + */ + size_t Read(T *Data, size_t nReads) { sl_guard(*Lock); size_t read = 0; - while (Size > 0) + while (nReads > 0) { if (BufferCount == 0) break; @@ -82,19 +119,29 @@ public: Tail = (Tail + 1) % BufferSize; BufferCount--; read++; - Size--; + nReads--; } return read; } - size_t Peek(T *Data, size_t Size) + /** + * @brief Peek at data in the ring buffer without removing it. + * + * Peeks up to `nReads` elements from the buffer into `Data` without + * modifying the buffer state. If the buffer is empty, the function stops peeking. + * + * @param Data Pointer to the memory where peeked elements will be stored. + * @param nReads Number of elements to peek. + * @return size_t Number of elements actually peeked. + */ + size_t Peek(T *Data, size_t nReads) { sl_guard(*Lock); size_t read = 0; size_t tail = Tail; - while (Size > 0) + while (nReads > 0) { if (BufferCount == 0) break; @@ -102,18 +149,28 @@ public: *Data++ = Buffer[tail]; tail = (tail + 1) % BufferSize; read++; - Size--; + nReads--; } return read; } + /** + * @brief Get the current number of elements in the buffer. + * + * @return size_t The number of elements in the buffer. + */ size_t Count() { sl_guard(*Lock); return BufferCount; } + /** + * @brief Get the available space left in the buffer. + * + * @return size_t The number of free slots in the buffer. + */ size_t Free() { sl_guard(*Lock);