From 92a6ba68f45292a444befae21b2cb90f920cfe6e Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 19 Dec 2022 21:01:59 +0100 Subject: [PATCH] Introduce FastCircularBuffer --- include/PSX/Auxiliary/array_range.hpp | 17 ++++++++ include/PSX/Auxiliary/circular_buffer.hpp | 51 +++++++++++++++-------- 2 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 include/PSX/Auxiliary/array_range.hpp diff --git a/include/PSX/Auxiliary/array_range.hpp b/include/PSX/Auxiliary/array_range.hpp new file mode 100644 index 00000000..19daa078 --- /dev/null +++ b/include/PSX/Auxiliary/array_range.hpp @@ -0,0 +1,17 @@ +#ifndef __JABYENGINE_ARRAY_RANGE_HPP__ +#define __JABYENGINE_ARRAY_RANGE_HPP__ +#include "../../stddef.h" + +namespace JabyEngine { + template + struct ArrayRange { + T* start = nullptr; + size_t size = 0; + + constexpr ArrayRange() = default; + constexpr ArrayRange(T* start, size_t size) : start(start), size(size) { + } + }; +} + +#endif //!__JABYENGINE_ARRAY_RANGE_HPP__ \ No newline at end of file diff --git a/include/PSX/Auxiliary/circular_buffer.hpp b/include/PSX/Auxiliary/circular_buffer.hpp index 4dc8ca32..694ce63e 100644 --- a/include/PSX/Auxiliary/circular_buffer.hpp +++ b/include/PSX/Auxiliary/circular_buffer.hpp @@ -1,40 +1,30 @@ #ifndef __JABYENGINE_CIRCULAR_BUFFER_HPP__ #define __JABYENGINE_CIRCULAR_BUFFER_HPP__ -#include "../../stddef.h" +#include "array_range.hpp" namespace JabyEngine { - class CircularBuffer { + template + class FastCircularBuffer { private: - typedef uint32_t T; - T* start_adr = nullptr; - size_t end_idx = 0; size_t read_idx = 0; size_t write_idx = 0; - static size_t increment(size_t cur_idx, size_t end_idx) { - static constexpr size_t Step = 1; - - cur_idx += Step; - if(cur_idx >= end_idx) { - return (end_idx - cur_idx); - } - - return cur_idx; + static size_t increment(size_t cur_idx, size_t step) { + return ((cur_idx + step) & (ElementCount - 1)); } public: - CircularBuffer() = default; + FastCircularBuffer() = default; void setup(T* buffer_start_adr, size_t element_count) { this->start_adr = buffer_start_adr; - this->end_idx = element_count; this->read_idx = 0; this->write_idx = 0; } - T* push() { - const auto new_idx = CircularBuffer::increment(this->write_idx, this->end_idx); + T* allocate() { + const auto new_idx = FastCircularBuffer::increment(this->write_idx, 1); if(new_idx != this->read_idx) { auto* dst = (this->start_adr + this->write_idx); @@ -45,9 +35,34 @@ namespace JabyEngine { return nullptr; } + const T* pop() { + if(this->write_idx != this->read_idx) { + const auto* src = (this->start_adr + this->read_idx); + FastCircularBuffer::drop(1); + + return src; + } + + return nullptr; + } + + void drop(size_t elements) { + this->read_idx = FastCircularBuffer::increment(this->read_idx, elements); + } + + constexpr ArrayRange get_first_continious() const { + return {&this->start_adr[this->read_idx], (this->write_idx >= this->read_idx) ? (this->write_idx - this->read_idx) : (ElementCount - this->read_idx)}; + } + + constexpr ArrayRange get_second_continious() const { + return {this->start_adr, (this->write_idx < this->read_idx) ? this->write_idx : 0}; + } + constexpr bool has_data() const { return (this->read_idx != this->write_idx); } + + static_assert(ElementCount == 2 || ElementCount == 4 || ElementCount == 8 || ElementCount == 16 || ElementCount == 32 || ElementCount == 64 || ElementCount == 128 || ElementCount == 256, "ElementCount for FastCircularBuffer must be power of 2"); }; }