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.