Squashed commit of the following:

commit 23c5f1d3f9b13ff9e46ce3de96aefeb655d5ed97
Author: John Wellbelove <github@wellbelove.co.uk>
Date:   Sun Jan 31 12:32:35 2021 +0000

    Fixed rollover error for etl::queue_spsc_atomic

    Added 'required_alignment' parameter to 'allocate' for etl::imemeory_block_allocator.
    Updated QueuedMessageRouter example
This commit is contained in:
John Wellbelove 2021-01-31 12:34:49 +00:00
parent 7bfdb53e0d
commit e5f4eb6fb3
27 changed files with 228 additions and 129 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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:

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\QueuedMessageRouter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\etl_profile.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -23,32 +23,32 @@
<ProjectGuid>{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>QueuedMessageRouter</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -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<block>();
}

View File

@ -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:

View File

@ -97,7 +97,7 @@ namespace etl
}
else
{
n = RESERVED - read_index + write_index - 1;
n = RESERVED - read_index + write_index;
}
return n;

View File

@ -117,7 +117,7 @@ namespace etl
prcm_t p = ETL_NULLPTR;
lock();
p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t)));
p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
unlock();
if (p != ETL_NULLPTR)

View File

@ -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)

View File

@ -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"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library ETL
version=19.5.1
version=19.5.2
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -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.

View File

@ -43,11 +43,11 @@ namespace
{
Allocator16 allocator16;
int16_t* p1 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p2 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p3 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p4 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p5 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p1 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
int16_t* p2 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
int16_t* p3 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
int16_t* p4 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(int16_t)));
int16_t* p5 = static_cast<int16_t*>(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<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p2 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p3 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p4 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p5 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p6 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p7 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p8 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p9 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p10 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p11 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p12 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p13 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t)));
int16_t* p1 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p2 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p3 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p4 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p5 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p6 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p7 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p8 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p9 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p10 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p11 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p12 = static_cast<int16_t*>(allocator16.allocate(sizeof(int16_t), alignof(uint16_t)));
int16_t* p13 = static_cast<int16_t*>(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<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
int16_t* p2 = static_cast<int16_t*>(allocator8.allocate(sizeof(int16_t))); // Take from allocator16
int32_t* p3 = static_cast<int32_t*>(allocator8.allocate(sizeof(int32_t))); // Take from allocator32
int64_t* p4 = static_cast<int64_t*>(allocator8.allocate(sizeof(int64_t))); // Unable to allocate
int8_t* p5 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
int8_t* p6 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator8
int8_t* p7 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator8. allocator8 is full.
int8_t* p8 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator16
int8_t* p9 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator16
int8_t* p10 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator16. allocator16 is full.
int8_t* p11 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t))); // Take from allocator32
int8_t* p1 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
int16_t* p2 = static_cast<int16_t*>(allocator8.allocate(sizeof(int16_t), alignof(uint16_t))); // Take from allocator16
int32_t* p3 = static_cast<int32_t*>(allocator8.allocate(sizeof(int32_t), alignof(uint32_t))); // Take from allocator32
int64_t* p4 = static_cast<int64_t*>(allocator8.allocate(sizeof(int64_t), alignof(uint64_t))); // Unable to allocate
int8_t* p5 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
int8_t* p6 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8
int8_t* p7 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator8. allocator8 is full.
int8_t* p8 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16
int8_t* p9 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16
int8_t* p10 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator16. allocator16 is full.
int8_t* p11 = static_cast<int8_t*>(allocator8.allocate(sizeof(int8_t), alignof(uint8_t))); // Take from allocator32
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);

View File

@ -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());

View File

@ -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());

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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));

View File

@ -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());

View File

@ -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());

View File

@ -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());

View File

@ -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());

View File

@ -1288,6 +1288,7 @@
<ClInclude Include="..\..\include\etl\generators\type_traits_generator.h" />
<ClInclude Include="..\..\include\etl\generators\variant_pool_generator.h" />
<ClInclude Include="..\..\include\etl\generic_pool.h" />
<ClInclude Include="..\..\include\etl\imemory_block_allocator.h" />
<ClInclude Include="..\..\include\etl\indirect_vector.h" />
<ClInclude Include="..\..\include\etl\absolute.h" />
<ClInclude Include="..\..\include\etl\ipool.h" />

View File

@ -945,6 +945,9 @@
<ClInclude Include="..\..\include\etl\successor.h">
<Filter>ETL\Patterns</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\imemory_block_allocator.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp">