diff --git a/src/core/include/core/buffer/buffer_interface.hpp b/src/core/include/core/buffer/buffer_interface.hpp index 555b485..2cc36c6 100644 --- a/src/core/include/core/buffer/buffer_interface.hpp +++ b/src/core/include/core/buffer/buffer_interface.hpp @@ -35,6 +35,11 @@ class BufferInterface : public BufferBase { /// \return 0 if failed, otherwise the number of bytes written (1) virtual std::size_t Write(const T& data) = 0; + /// \brief Peek at the most recent data without consuming it + /// \param data reference to store the peeked data + /// \return 0 if failed, otherwise 1 + virtual std::size_t Peek(T& data) const = 0; + /// \brief Read data from the buffer (burst read) /// \param data /// \return 0 if failed, otherwise the number of bytes read diff --git a/src/core/include/core/buffer/double_buffer.hpp b/src/core/include/core/buffer/double_buffer.hpp index 46c2fd4..452b204 100644 --- a/src/core/include/core/buffer/double_buffer.hpp +++ b/src/core/include/core/buffer/double_buffer.hpp @@ -61,11 +61,22 @@ class DoubleBuffer : public BufferInterface { return true; } + std::size_t Peek(T& data) const { + std::lock_guard lock(mutex_); + if (!ready_.load(std::memory_order_acquire)) { + return 0; + } + + int read_index = 1 - write_index_; + data = buffer_[read_index]; + return 1; + } + private: T buffer_[2]; int write_index_; std::atomic ready_{false}; - std::mutex mutex_; + mutable std::mutex mutex_; std::condition_variable cond_var_; }; } // namespace quickviz diff --git a/src/core/include/core/buffer/ring_buffer.hpp b/src/core/include/core/buffer/ring_buffer.hpp index fe54b5b..f5423c5 100644 --- a/src/core/include/core/buffer/ring_buffer.hpp +++ b/src/core/include/core/buffer/ring_buffer.hpp @@ -138,6 +138,15 @@ class RingBuffer : public BufferInterface { return count; } + // Get the most recent data + std::size_t Peek(T& data) const override { + std::lock_guard lock(buffer_mutex_); + std::size_t occupied_size = (write_index_ - read_index_) & size_mask_; + if (occupied_size == 0) return 0; + data = buffer_[(write_index_ - 1) & size_mask_]; + return 1; + } + std::size_t Write(const std::vector& new_data, std::size_t btw) override { assert(new_data.size() >= btw); std::lock_guard lock(buffer_mutex_);