diff --git a/.gitignore b/.gitignore
index 877c2b1d..45c37380 100644
--- a/.gitignore
+++ b/.gitignore
@@ -285,3 +285,4 @@ examples/FunctionInterruptSimulation-Delegates/vs2019/.vs
*.db-shm
test/vs2019/.vs/etl/v16/Browse.VC.db-wal
examples/SharedMessage/.vs
+examples/QueuedMessageRouter/vs2019/.vs
diff --git a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp
index f635709e..a392db95 100644
--- a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp
+++ b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp
@@ -67,13 +67,16 @@ public:
if (accepts(msg_))
{
// Place in queue.
+
+ Item item(&sender_, msg_);
+
queue.emplace(&sender_, msg_);
- std::cout << "Queueing message " << int(msg_.message_id) << std::endl;
+ std::cout << "Queueing message " << int(msg_.get_message_id()) << std::endl;
}
else
{
- std::cout << "Ignoring message " << int(msg_.message_id) << std::endl;
+ std::cout << "Ignoring message " << int(msg_.get_message_id()) << std::endl;
}
}
@@ -85,7 +88,7 @@ public:
Item& item = queue.front();
etl::imessage& msg = item.packet.get();
etl::imessage_router& sender = *item.sender;
- std::cout << "Processing message " << int(msg.message_id) << std::endl;
+ std::cout << "Processing message " << int(msg.get_message_id()) << std::endl;
// Call the base class's receive function.
// This will route it to the correct on_receive handler.
@@ -98,25 +101,25 @@ public:
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message1& msg)
{
- std::cout << " Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl;
+ std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.i << "'" << std::endl;
}
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message2& msg)
{
- std::cout << " Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl;
+ std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.d << "'" << std::endl;
}
//***************************************************************************
void on_receive(etl::imessage_router& sender, const Message3& msg)
{
- std::cout << " Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl;
+ std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.s << "'" << std::endl;
}
//***************************************************************************
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
{
- std::cout << " Received unknown message " << int(msg.message_id) << std::endl;
+ std::cout << " Received unknown message " << int(msg.get_message_id()) << std::endl;
}
private:
diff --git a/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite b/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite
deleted file mode 100644
index 2572d76e..00000000
Binary files a/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite and /dev/null differ
diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters b/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters
deleted file mode 100644
index 795b7698..00000000
--- a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- Source Files
-
-
-
-
- Header Files
-
-
-
\ No newline at end of file
diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.sln b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.sln
similarity index 100%
rename from examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.sln
rename to examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.sln
diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj
similarity index 96%
rename from examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj
rename to examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj
index 2c3eba2a..65dad150 100644
--- a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj
+++ b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj
@@ -23,32 +23,32 @@
{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}
Win32Proj
QueuedMessageRouter
- 10.0.18362.0
+ 10.0
Application
true
- v141
+ v142
Unicode
Application
false
- v141
+ v142
true
Unicode
Application
true
- v141
+ v142
Unicode
Application
false
- v141
+ v142
true
Unicode
diff --git a/include/etl/fixed_sized_memory_block_allocator.h b/include/etl/fixed_sized_memory_block_allocator.h
index ae3e217f..3e70641b 100644
--- a/include/etl/fixed_sized_memory_block_allocator.h
+++ b/include/etl/fixed_sized_memory_block_allocator.h
@@ -80,9 +80,11 @@ namespace etl
//*************************************************************************
/// The overridden virtual function to allocate a block.
//*************************************************************************
- virtual void* allocate_block(size_t required_size) ETL_OVERRIDE
+ virtual void* allocate_block(size_t required_size, size_t required_alignment) ETL_OVERRIDE
{
- if ((required_size <= Block_Size) && !pool.full())
+ if ((required_alignment <= Alignment) &&
+ (required_size <= Block_Size) &&
+ !pool.full())
{
return pool.template allocate();
}
diff --git a/include/etl/imemory_block_allocator.h b/include/etl/imemory_block_allocator.h
index aed1493d..5b8529a2 100644
--- a/include/etl/imemory_block_allocator.h
+++ b/include/etl/imemory_block_allocator.h
@@ -55,10 +55,10 @@ namespace etl
/// Try to allocate a memory block of the required size.
/// If this allocator cannot, then pass the request on the the successor, if configured.
//*****************************************************************************
- void* allocate(size_t required_size)
+ void* allocate(size_t required_size, size_t required_alignment)
{
// Call the derived implementation.
- void* p = allocate_block(required_size);
+ void* p = allocate_block(required_size, required_alignment);
// If that failed...
if (p == ETL_NULLPTR)
@@ -67,7 +67,7 @@ namespace etl
if (has_successor())
{
// Try to allocate from the next one in the chain.
- return get_successor().allocate(required_size);
+ return get_successor().allocate(required_size, required_alignment);
}
}
@@ -98,7 +98,7 @@ namespace etl
protected:
- virtual void* allocate_block(size_t required_size) = 0;
+ virtual void* allocate_block(size_t required_size, size_t required_alignment) = 0;
virtual bool release_block(const void* const) = 0;
private:
diff --git a/include/etl/queue_spsc_atomic.h b/include/etl/queue_spsc_atomic.h
index 3501ebdc..13e496a8 100644
--- a/include/etl/queue_spsc_atomic.h
+++ b/include/etl/queue_spsc_atomic.h
@@ -97,7 +97,7 @@ namespace etl
}
else
{
- n = RESERVED - read_index + write_index - 1;
+ n = RESERVED - read_index + write_index;
}
return n;
diff --git a/include/etl/reference_counted_message_pool.h b/include/etl/reference_counted_message_pool.h
index 2bc45e08..8003983f 100644
--- a/include/etl/reference_counted_message_pool.h
+++ b/include/etl/reference_counted_message_pool.h
@@ -117,7 +117,7 @@ namespace etl
prcm_t p = ETL_NULLPTR;
lock();
- p = static_cast(memory_block_allocator.allocate(sizeof(rcm_t)));
+ p = static_cast(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of::value));
unlock();
if (p != ETL_NULLPTR)
diff --git a/include/etl/version.h b/include/etl/version.h
index df94a637..f322966d 100644
--- a/include/etl/version.h
+++ b/include/etl/version.h
@@ -39,7 +39,7 @@ SOFTWARE.
#define ETL_VERSION_MAJOR 19
#define ETL_VERSION_MINOR 5
-#define ETL_VERSION_PATCH 1
+#define ETL_VERSION_PATCH 2
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_U16 ETL_STRINGIFY(ETL_VERSION_MAJOR) u"." ETL_STRINGIFY(ETL_VERSION_MINOR) u"." ETL_STRINGIFY(ETL_VERSION_PATCH)
diff --git a/library.json b/library.json
index c894dcd5..4d2a3654 100644
--- a/library.json
+++ b/library.json
@@ -1,6 +1,6 @@
{
"name": "ETL Embedded Template Library",
- "version": "19.5.1",
+ "version": "19.5.2",
"author s": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"
diff --git a/library.properties b/library.properties
index 74b20470..f45cfaeb 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=Embedded Template Library ETL
-version=19.5.1
+version=19.5.2
author= John Wellbelove
maintainer=John Wellbelove
license=MIT
diff --git a/support/Release notes.txt b/support/Release notes.txt
index a53ce710..21d306e3 100644
--- a/support/Release notes.txt
+++ b/support/Release notes.txt
@@ -1,3 +1,9 @@
+===============================================================================
+19.5.2
+Fixed rollover error for etl::queue_spsc_atomic
+Added 'required_alignment' parameter to 'allocate' for etl::imemeory_block_allocator.
+Updated QueuedMessageRouter example.
+
===============================================================================
19.5.1
Exclude integral types from being considered for iterator range container constructors.
diff --git a/test/test_fixed_sized_memory_block_allocator.cpp b/test/test_fixed_sized_memory_block_allocator.cpp
index bbcd5f21..4767d53b 100644
--- a/test/test_fixed_sized_memory_block_allocator.cpp
+++ b/test/test_fixed_sized_memory_block_allocator.cpp
@@ -43,11 +43,11 @@ namespace
{
Allocator16 allocator16;
- int16_t* p1 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p2 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p3 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p4 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p5 = static_cast(allocator16.allocate(sizeof(int16_t)));
+ int16_t* p1 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
+ int16_t* p2 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
+ int16_t* p3 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
+ int16_t* p4 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
+ int16_t* p5 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);
@@ -87,19 +87,19 @@ namespace
allocator16.set_successor(allocator16s);
allocator16s.set_successor(allocator16ss);
- int16_t* p1 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p2 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p3 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p4 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p5 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p6 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p7 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p8 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p9 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p10 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p11 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p12 = static_cast(allocator16.allocate(sizeof(int16_t)));
- int16_t* p13 = static_cast(allocator16.allocate(sizeof(int16_t)));
+ int16_t* p1 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p2 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p3 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p4 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p5 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p6 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p7 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p8 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p9 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p10 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p11 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p12 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
+ int16_t* p13 = static_cast(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);
@@ -140,17 +140,17 @@ namespace
allocator8.set_successor(allocator16);
allocator16.set_successor(allocator32);
- int8_t* p1 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
- int16_t* p2 = static_cast(allocator8.allocate(sizeof(int16_t))); // Take from allocator16
- int32_t* p3 = static_cast(allocator8.allocate(sizeof(int32_t))); // Take from allocator32
- int64_t* p4 = static_cast(allocator8.allocate(sizeof(int64_t))); // Unable to allocate
- int8_t* p5 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
- int8_t* p6 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
- int8_t* p7 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator8. allocator8 is full.
- int8_t* p8 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator16
- int8_t* p9 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator16
- int8_t* p10 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator16. allocator16 is full.
- int8_t* p11 = static_cast(allocator8.allocate(sizeof(int8_t))); // Take from allocator32
+ int8_t* p1 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
+ int16_t* p2 = static_cast(allocator8.allocate(sizeof(int16_t), alignof(uint16_t))); // Take from allocator16
+ int32_t* p3 = static_cast(allocator8.allocate(sizeof(int32_t), alignof(uint32_t))); // Take from allocator32
+ int64_t* p4 = static_cast(allocator8.allocate(sizeof(int64_t), alignof(uint64_t))); // Unable to allocate
+ int8_t* p5 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
+ int8_t* p6 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
+ int8_t* p7 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8. allocator8 is full.
+ int8_t* p8 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16
+ int8_t* p9 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16
+ int8_t* p10 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16. allocator16 is full.
+ int8_t* p11 = static_cast(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator32
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);
diff --git a/test/test_queue_lockable.cpp b/test/test_queue_lockable.cpp
index b6f0b6d3..65edaa50 100644
--- a/test/test_queue_lockable.cpp
+++ b/test/test_queue_lockable.cpp
@@ -244,15 +244,26 @@ namespace
queue.clear_test_flags();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
queue.clear_test_flags();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(3U, queue.size());
@@ -260,7 +271,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(2U, queue.size());
@@ -268,7 +279,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(1U, queue.size());
@@ -276,7 +287,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(0U, queue.size());
diff --git a/test/test_queue_lockable_small.cpp b/test/test_queue_lockable_small.cpp
index 994dec72..d4351e06 100644
--- a/test/test_queue_lockable_small.cpp
+++ b/test/test_queue_lockable_small.cpp
@@ -244,15 +244,26 @@ namespace
queue.clear_test_flags();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
queue.clear_test_flags();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(3U, queue.size());
@@ -260,7 +271,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(2U, queue.size());
@@ -268,7 +279,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(1U, queue.size());
@@ -276,7 +287,7 @@ namespace
queue.clear_test_flags();
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(queue.called_lock);
CHECK(queue.called_unlock);
CHECK_EQUAL(0U, queue.size());
diff --git a/test/test_queue_mpmc_mutex.cpp b/test/test_queue_mpmc_mutex.cpp
index ebe0edbd..ee2b4a54 100644
--- a/test/test_queue_mpmc_mutex.cpp
+++ b/test/test_queue_mpmc_mutex.cpp
@@ -117,25 +117,36 @@ namespace
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(0U, queue.available());
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK_EQUAL(0U, queue.size());
CHECK(!queue.pop(i));
diff --git a/test/test_queue_mpmc_mutex_small.cpp b/test/test_queue_mpmc_mutex_small.cpp
index 1f5ad387..fdf087ec 100644
--- a/test/test_queue_mpmc_mutex_small.cpp
+++ b/test/test_queue_mpmc_mutex_small.cpp
@@ -129,25 +129,36 @@ namespace
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(0U, queue.available());
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK_EQUAL(0U, queue.size());
CHECK(!queue.pop(i));
diff --git a/test/test_queue_spsc_atomic.cpp b/test/test_queue_spsc_atomic.cpp
index 64a2df05..a4e20694 100644
--- a/test/test_queue_spsc_atomic.cpp
+++ b/test/test_queue_spsc_atomic.cpp
@@ -114,25 +114,36 @@ namespace
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(0U, queue.available());
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK_EQUAL(0U, queue.size());
CHECK(!queue.pop(i));
diff --git a/test/test_queue_spsc_atomic_small.cpp b/test/test_queue_spsc_atomic_small.cpp
index ce4a5274..1a50fdad 100644
--- a/test/test_queue_spsc_atomic_small.cpp
+++ b/test/test_queue_spsc_atomic_small.cpp
@@ -119,25 +119,36 @@ namespace
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(0U, queue.available());
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK_EQUAL(0U, queue.size());
CHECK(!queue.pop(i));
diff --git a/test/test_queue_spsc_isr.cpp b/test/test_queue_spsc_isr.cpp
index eaf559aa..286f73d1 100644
--- a/test/test_queue_spsc_isr.cpp
+++ b/test/test_queue_spsc_isr.cpp
@@ -184,15 +184,26 @@ namespace
Access::clear();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push_from_isr(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
Access::clear();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(Access::called_lock);
CHECK(Access::called_unlock);
CHECK_EQUAL(3U, queue.size_from_isr());
@@ -200,7 +211,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(2U, queue.size_from_isr());
@@ -208,7 +219,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(1U, queue.size_from_isr());
@@ -216,7 +227,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(0U, queue.size_from_isr());
diff --git a/test/test_queue_spsc_isr_small.cpp b/test/test_queue_spsc_isr_small.cpp
index ff19db76..1ce8e8e7 100644
--- a/test/test_queue_spsc_isr_small.cpp
+++ b/test/test_queue_spsc_isr_small.cpp
@@ -189,15 +189,26 @@ namespace
Access::clear();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push_from_isr(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
Access::clear();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(Access::called_lock);
CHECK(Access::called_unlock);
CHECK_EQUAL(3U, queue.size_from_isr());
@@ -205,7 +216,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(2U, queue.size_from_isr());
@@ -213,7 +224,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(1U, queue.size_from_isr());
@@ -221,7 +232,7 @@ namespace
Access::clear();
CHECK(queue.pop_from_isr(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(!Access::called_lock);
CHECK(!Access::called_unlock);
CHECK_EQUAL(0U, queue.size_from_isr());
diff --git a/test/test_queue_spsc_locked.cpp b/test/test_queue_spsc_locked.cpp
index 09d53c94..6abe7c92 100644
--- a/test/test_queue_spsc_locked.cpp
+++ b/test/test_queue_spsc_locked.cpp
@@ -187,15 +187,26 @@ namespace
access.clear();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push_from_unlocked(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
access.clear();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(access.called_lock);
CHECK(access.called_unlock);
CHECK_EQUAL(3U, queue.size_from_unlocked());
@@ -203,7 +214,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(2U, queue.size_from_unlocked());
@@ -211,7 +222,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(1U, queue.size_from_unlocked());
@@ -219,7 +230,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(0U, queue.size_from_unlocked());
diff --git a/test/test_queue_spsc_locked_small.cpp b/test/test_queue_spsc_locked_small.cpp
index c55784d1..93cd822f 100644
--- a/test/test_queue_spsc_locked_small.cpp
+++ b/test/test_queue_spsc_locked_small.cpp
@@ -191,15 +191,26 @@ namespace
access.clear();
+ // Queue full.
CHECK(!queue.push(5));
- CHECK(!queue.push_from_unlocked(5));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(5));
+
+ // Queue full.
+ CHECK(!queue.push(6));
+
+ queue.pop();
+ // Queue not full (buffer rollover)
+ CHECK(queue.push(6));
access.clear();
int i;
CHECK(queue.pop(i));
- CHECK_EQUAL(1, i);
+ CHECK_EQUAL(3, i);
CHECK(access.called_lock);
CHECK(access.called_unlock);
CHECK_EQUAL(3U, queue.size_from_unlocked());
@@ -207,7 +218,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(2, i);
+ CHECK_EQUAL(4, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(2U, queue.size_from_unlocked());
@@ -215,7 +226,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(3, i);
+ CHECK_EQUAL(5, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(1U, queue.size_from_unlocked());
@@ -223,7 +234,7 @@ namespace
access.clear();
CHECK(queue.pop_from_unlocked(i));
- CHECK_EQUAL(4, i);
+ CHECK_EQUAL(6, i);
CHECK(!access.called_lock);
CHECK(!access.called_unlock);
CHECK_EQUAL(0U, queue.size_from_unlocked());
diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj
index e24ebbb2..3aa2fa84 100644
--- a/test/vs2019/etl.vcxproj
+++ b/test/vs2019/etl.vcxproj
@@ -1288,6 +1288,7 @@
+
diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters
index a8a96076..cda71eb1 100644
--- a/test/vs2019/etl.vcxproj.filters
+++ b/test/vs2019/etl.vcxproj.filters
@@ -945,6 +945,9 @@
ETL\Patterns
+
+ ETL\Containers
+