From 8151edeebfd7ddda822cceebfb9b35a09de78274 Mon Sep 17 00:00:00 2001 From: zongor Date: Thu, 24 Jul 2025 00:16:52 -0400 Subject: [PATCH] update ring buffer --- src/ring_buffer.h | 84 ++++++++++++++++++++++++++++------------------ src/simulation.cpp | 38 ++++++++++----------- src/simulation.h | 2 +- 3 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/ring_buffer.h b/src/ring_buffer.h index dfa0064..c48c0bb 100644 --- a/src/ring_buffer.h +++ b/src/ring_buffer.h @@ -1,51 +1,71 @@ #ifndef RING_BUFFER_H #define RING_BUFFER_H -#include -#include -#include +#include +#include +#include -template -class RingBuffer { - static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be power of 2"); +template class RingBuffer { + std::vector buffer; + size_t capacity; + size_t head; + size_t tail; + bool full; -private: - std::array buffer; - std::atomic head = 0; // write index - std::atomic tail = 0; // read index + mutable std::mutex mtx; + bool empty_unlocked() const { return (!full && (head == tail)); } public: - bool push(const T& item) { - size_t current_head = head.load(std::memory_order_relaxed); - size_t next_head = (current_head + 1) & (Capacity - 1); + explicit RingBuffer(size_t capacity) + : buffer(capacity), capacity(capacity), head(0), tail(0), full(false) {} - if (next_head == tail.load(std::memory_order_acquire)) { - return false; // buffer full - } - - buffer[current_head] = item; - head.store(next_head, std::memory_order_release); - return true; + bool push(const T &item) { + std::lock_guard lock(mtx); + if (full) { + return false; } - bool pop(T& item) { - size_t current_tail = tail.load(std::memory_order_relaxed); - if (current_tail == head.load(std::memory_order_acquire)) { - return false; // buffer empty - } + buffer[tail] = item; + tail = (tail + 1) % capacity; + full = (tail == head); + return true; + } - item = buffer[current_tail]; - tail.store((current_tail + 1) & (Capacity - 1), std::memory_order_release); - return true; + std::optional pop() { + std::lock_guard lock(mtx); + + if (empty_unlocked()) { + return std::nullopt; } - bool empty() const { - return head.load() == tail.load(); + T item = buffer[head]; + full = false; + head = (head + 1) % capacity; + } + + bool empty() const { + std::lock_guard lock(mtx); + return empty_unlocked(); + } + + bool full_() const { + std::lock_guard lock(mtx); + return full; + } + + size_t size() const { + std::lock_guard lock(mtx); + + if (full) { + return capacity; } - bool full() const { - return ((head.load() + 1) & (Capacity - 1)) == tail.load(); + if (tail >= head) { + return tail - head; } + + return capacity + tail - head; + } }; #endif diff --git a/src/simulation.cpp b/src/simulation.cpp index 29d4bd9..97d861a 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -4,33 +4,31 @@ #include std::atomic running(true); -RingBuffer snapshot_buffer; +RingBuffer snapshot_buffer(128); void simulation_loop(std::shared_ptr state) { - Vec3 velocity(0.01, 0.02, 0.03); + Vec3 velocity(0.01, 0.02, 0.03); - while (running) { - // Update position - for (auto &p : state->positions) { - p += velocity; - } - - // Push latest position to buffer - if (!snapshot_buffer.push(state->positions[0])) { - std::cerr << "Snapshot buffer full, dropping frame\n"; - } + while (running) { + for (auto &p : state->positions) { + p += velocity; } + + while (snapshot_buffer.push(state->positions[0])) { + std::this_thread::yield(); + } + } } void render_loop() { - Vec3 latest; + while (running) { - while (running) { - while (snapshot_buffer.pop(latest)) { - std::cout << "[Render] "; - latest.print(); - } - // Optional: add very short pause to avoid spinning too fast - std::this_thread::yield(); // cooperative multitasking + Vec3 latest; + while (latest = snapshot_buffer.pop()) { + std::cout << "[Render] "; + latest.print(); } + // Optional: add very short pause to avoid spinning too fast + std::this_thread::yield(); // cooperative multitasking + } } diff --git a/src/simulation.h b/src/simulation.h index 953b24c..b3444ec 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -13,7 +13,7 @@ struct SimulationState { }; extern std::atomic running; -extern RingBuffer snapshot_buffer; +extern RingBuffer snapshot_buffer; void simulation_loop(std::shared_ptr state); void render_loop();