From ed0dbc00c23dd0343dbf999abecca9ccdc5ffdd0 Mon Sep 17 00:00:00 2001 From: Benedek Kupper <57992871+bku-sue@users.noreply.github.com> Date: Fri, 16 Jul 2021 12:42:35 +0200 Subject: [PATCH] Feature/bip buffer spsc atomic (#402 follow-up) (#404) * bip_buffer_spsc_atomic: fix compiler failure The previous commit changed the pointer being const (cannot change where the pointer is pointing after construction) to the referred data to be const (the buffer itself is not writeable), which causes compiler issue with the tests. Signed-off-by: Benedek Kupper * bip_buffer_spsc_atomic: whitespace cleanup for consistency Signed-off-by: Benedek Kupper * bip_buffer_spsc_atomic: clear() destroys the unread data Signed-off-by: Benedek Kupper * bip_buffer_spsc_atomic: add destructor Signed-off-by: Benedek Kupper --- include/etl/bip_buffer_spsc_atomic.h | 60 +++++++++++++++++++++------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/include/etl/bip_buffer_spsc_atomic.h b/include/etl/bip_buffer_spsc_atomic.h index 100fc961..4b2427aa 100644 --- a/include/etl/bip_buffer_spsc_atomic.h +++ b/include/etl/bip_buffer_spsc_atomic.h @@ -45,6 +45,7 @@ SOFTWARE. #include "alignment.h" #include "parameter_type.h" #include "atomic.h" +#include "memory.h" #include "memory_model.h" #include "integral_limits.h" #include "utility.h" @@ -177,18 +178,8 @@ namespace etl return RESERVED; } - //************************************************************************* - /// Clears the buffer. - //************************************************************************* - void clear() - { - read.store(0, etl::memory_order_release); - write.store(0, etl::memory_order_release); - last.store(0, etl::memory_order_release); - } - protected: - + //************************************************************************* /// Construccts the buffer. //************************************************************************* @@ -200,6 +191,14 @@ namespace etl { } + //************************************************************************* + void reset() + { + read.store(0, etl::memory_order_release); + write.store(0, etl::memory_order_release); + last.store(0, etl::memory_order_release); + } + //************************************************************************* size_type get_write_reserve(size_type* psize) { @@ -344,6 +343,7 @@ namespace etl #if defined(ETL_POLYMORPHIC_SPSC_BIP_BUFFER_ATOMIC) || defined(ETL_POLYMORPHIC_CONTAINERS) public: + virtual ~bip_buffer_spsc_atomic_base() { } @@ -363,15 +363,16 @@ namespace etl class ibip_buffer_spsc_atomic : public bip_buffer_spsc_atomic_base { private: - + typedef typename etl::bip_buffer_spsc_atomic_base base_t; + using base_t::reset; using base_t::get_read_reserve; using base_t::apply_read_reserve; using base_t::get_write_reserve; using base_t::apply_write_reserve; public: - + typedef T value_type; ///< The type stored in the buffer. typedef T& reference; ///< A reference to the type used in the buffer. typedef const T& const_reference; ///< A const reference to the type used in the buffer. @@ -380,6 +381,8 @@ namespace etl #endif typedef typename base_t::size_type size_type; ///< The type used for determining the size of the buffer. + using base_t::max_size; + //************************************************************************* // Reserves a memory area for reading up to the max_reserve_size //************************************************************************* @@ -424,6 +427,24 @@ namespace etl apply_write_reserve(windex, reserve.size()); } + //************************************************************************* + /// Clears the buffer, destructing any elements that haven't been read. + //************************************************************************* + void clear() + { + // the buffer might be split into two contiguous blocks + for (auto reader = read_reserve(max_size()); reader.size() > 0; reader = read_reserve(max_size())) + { + destroy(reader.begin(), reader.end()); + read_commit(reader); + } + // now the buffer is already empty + // resetting the buffer here is beneficial to have + // the whole buffer available for a single block, + // but it requires synchronization between the writer and reader threads + reset(); + } + protected: //************************************************************************* @@ -444,7 +465,7 @@ namespace etl ibip_buffer_spsc_atomic& operator =(ibip_buffer_spsc_atomic&&) = delete; #endif - const T* p_buffer; + T* const p_buffer; }; //*************************************************************************** @@ -475,11 +496,22 @@ namespace etl static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE); + //************************************************************************* + /// Default constructor. + //************************************************************************* bip_buffer_spsc_atomic() : base_t(reinterpret_cast(&buffer[0]), RESERVED_SIZE) { } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~bip_buffer_spsc_atomic() + { + base_t::clear(); + } + private: /// The uninitialised buffer of T used in the bip_buffer_spsc.