Ongoing addition of unit tests

This commit is contained in:
John Wellbelove 2021-01-06 21:18:18 +00:00
parent 0b2bf0e47c
commit 2d612b0409
8 changed files with 293 additions and 115 deletions

View File

@ -7,7 +7,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 jwellbelove
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
@ -32,7 +32,7 @@ SOFTWARE.
#define ETL_FIXED_MEMORY_BLOCK_POOL_INCLUDED
#include "platform.h"
#include "memory.h"
#include "imemory_block_allocator.h"
#include "generic_pool.h"
#include "alignment.h"
@ -42,23 +42,19 @@ namespace etl
/// The fixed sized memory block pool.
/// The allocated memory blocks are all the same size.
//*************************************************************************
template <size_t Block_Size, size_t Alignment, size_t Size>
template <size_t VBlock_Size, size_t VAlignment, size_t VSize>
class fixed_sized_memory_block_allocator : public imemory_block_allocator
{
public:
//*************************************************************************
/// Default contsrcutor
//*************************************************************************
fixed_sized_memory_block_allocator()
{
}
static ETL_CONSTANT size_t Block_Size = VBlock_Size;
static ETL_CONSTANT size_t Alignment = VAlignment;
static ETL_CONSTANT size_t Size = VSize;
//*************************************************************************
/// Construct with a successor allocator.
/// Default constructor
//*************************************************************************
fixed_sized_memory_block_allocator(etl::imemory_block_allocator& successor)
: imemory_block_allocator(successor)
fixed_sized_memory_block_allocator()
{
}
@ -75,7 +71,7 @@ namespace etl
//*************************************************************************
virtual void* allocate_block(size_t required_size) ETL_OVERRIDE
{
if (required_size <= Block_Size)
if ((required_size <= Block_Size) && !pool.full())
{
return pool.template allocate<block>();
}

View File

@ -0,0 +1,134 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_MEMORY_BLOCK_ALLOCATOR_INCLUDED
#define ETL_MEMORY_BLOCK_ALLOCATOR_INCLUDED
#include "platform.h"
#include "nullptr.h"
namespace etl
{
//*****************************************************************************
/// The interface for a memory block pool.
//*****************************************************************************
class imemory_block_allocator
{
public:
//*****************************************************************************
/// Default constructor.
//*****************************************************************************
imemory_block_allocator()
: p_successor(ETL_NULLPTR)
{
}
//*****************************************************************************
/// 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)
{
// Call the derived implementation.
void* p = allocate_block(required_size);
// If that failed...
if (p == ETL_NULLPTR)
{
/// ...and we have a successor...
if (has_successor())
{
// Try to allocate from the next one in the chain.
return get_successor().allocate(required_size);
}
}
return p;
}
//*****************************************************************************
/// Try to release a memory block of the required size.
/// If this allocator cannot, then pass the request on the the successor, if configured.
//*****************************************************************************
bool release(const void* const p)
{
bool successful = release_block(p);
// Call the derived implementation to try to release.
if (!successful)
{
// If it failed and we have a successor...
if (has_successor())
{
// Try to release from the next one in the chain.
successful = get_successor().release(p);
}
}
return successful;
}
//*****************************************************************************
/// Set the sucessor allocator.
//*****************************************************************************
void set_successor(etl::imemory_block_allocator& successor)
{
p_successor = &successor;
}
//*****************************************************************************
/// Get the sucessor allocator.
//*****************************************************************************
etl::imemory_block_allocator& get_successor() const
{
return *p_successor;
}
//*****************************************************************************
/// Do we have a successor allocator.
//*****************************************************************************
bool has_successor() const
{
return (p_successor != ETL_NULLPTR);
}
protected:
virtual void* allocate_block(size_t required_size) = 0;
virtual bool release_block(const void* const) = 0;
private:
etl::imemory_block_allocator* p_successor;
};
}
#endif

View File

@ -1900,106 +1900,6 @@ namespace etl
}
};
//*****************************************************************************
/// The interface for a memory block pool.
//*****************************************************************************
class imemory_block_allocator
{
public:
//*****************************************************************************
/// Default constructor.
//*****************************************************************************
imemory_block_allocator()
: p_successor(ETL_NULLPTR)
{
}
//*****************************************************************************
/// Construct with a successor.
//*****************************************************************************
explicit imemory_block_allocator(imemory_block_allocator& successor)
: p_successor(&successor)
{
}
//*****************************************************************************
/// 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)
{
// Call the derived implementation.
void* p = allocate_block(required_size);
// If that failed...
if (p == ETL_NULLPTR)
{
/// ...and we have a successor...
if (has_successor())
{
// Try to allocate from the next one in the chain.
return get_successor().allocate(required_size);
}
}
return p;
}
//*****************************************************************************
/// Try to release a memory block of the required size.
/// If this allocator cannot, then pass the request on the the successor, if configured.
//*****************************************************************************
bool release(const void* const p)
{
// Call the derived implementation to try to release.
if (!release_block(p))
{
// If it failed and we have a successor...
if (has_successor())
{
// Try to release from the next one in the chain.
return get_successor().release(p);
}
}
return true;
}
//*****************************************************************************
/// Set the sucessor allocator.
//*****************************************************************************
void set_successor(etl::imemory_block_allocator& successor)
{
p_successor = &successor;
}
//*****************************************************************************
/// Get the sucessor allocator.
//*****************************************************************************
etl::imemory_block_allocator& get_successor() const
{
return *p_successor;
}
//*****************************************************************************
/// Do we have a successor allocator.
//*****************************************************************************
bool has_successor() const
{
return (p_successor != ETL_NULLPTR);
}
protected:
virtual void* allocate_block(size_t required_size) = 0;
virtual bool release_block(const void* const) = 0;
private:
etl::imemory_block_allocator* p_successor;
};
//***************************************************************************
/// Declares an aligned buffer of N_Objects x of size Object_Size at alignment Alignment.
///\ingroup alignment

View File

@ -5,7 +5,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 jwellbelove
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,7 +5,7 @@
//https://github.com/ETLCPP/etl
//https://www.etlcpp.com
//
//Copyright(c) 2020 jwellbelove
//Copyright(c) 2021 jwellbelove
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files(the "Software"), to deal

View File

@ -0,0 +1,144 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2020 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "UnitTest++/UnitTest++.h"
#include "etl/fixed_sized_memory_block_allocator.h"
namespace
{
using Allocator8 = etl::fixed_sized_memory_block_allocator<sizeof(int8_t), alignof(int8_t), 4>;
using Allocator16 = etl::fixed_sized_memory_block_allocator<sizeof(int16_t), alignof(int16_t), 4>;
using Allocator32 = etl::fixed_sized_memory_block_allocator<sizeof(int32_t), alignof(int32_t), 4>;
SUITE(test_fixed_sized_memory_block_allocator)
{
//*************************************************************************
TEST(test_allocator_no_successor_use_all_allocation)
{
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)));
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);
CHECK(p3 != nullptr);
CHECK(p4 != nullptr);
CHECK(p5 == nullptr);
CHECK(allocator16.release(p1));
CHECK(allocator16.release(p2));
CHECK(allocator16.release(p3));
CHECK(allocator16.release(p4));
CHECK(!allocator16.release(p5));
}
//*************************************************************************
TEST(test_allocator_has_successors)
{
Allocator16 allocator16;
Allocator16 allocator16s;
Allocator16 allocator16ss;
allocator16.set_successor(allocator16s);
allocator16s.set_successor(allocator16ss);
CHECK(allocator16.has_successor() == true);
CHECK(allocator16s.has_successor() == true);
CHECK(allocator16ss.has_successor() == false);
}
//*************************************************************************
TEST(test_allocator_with_successors_use_all_allocation)
{
Allocator16 allocator16;
Allocator16 allocator16s;
Allocator16 allocator16ss;
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)));
CHECK(p1 != nullptr);
CHECK(p2 != nullptr);
CHECK(p3 != nullptr);
CHECK(p4 != nullptr);
CHECK(p5 != nullptr);
CHECK(p6 != nullptr);
CHECK(p7 != nullptr);
CHECK(p8 != nullptr);
CHECK(p9 != nullptr);
CHECK(p10 != nullptr);
CHECK(p11 != nullptr);
CHECK(p12 != nullptr);
CHECK(p13 == nullptr);
CHECK(allocator16.release(p1));
CHECK(allocator16.release(p2));
CHECK(allocator16.release(p3));
CHECK(allocator16.release(p4));
CHECK(allocator16.release(p5));
CHECK(allocator16.release(p6));
CHECK(allocator16.release(p7));
CHECK(allocator16.release(p8));
CHECK(allocator16.release(p9));
CHECK(allocator16.release(p10));
CHECK(allocator16.release(p11));
CHECK(allocator16.release(p12));
CHECK(!allocator16.release(p13));
}
//*************************************************************************
TEST(test_allocator_with_different_block_sized_successors_use_all_allocation)
{
Allocator8 allocator8;
Allocator16 allocator16;
Allocator32 allocator32;
allocator8.set_successor(allocator16);
allocator16.set_successor(allocator32);
}
}
}

View File

@ -1528,6 +1528,7 @@
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
<ClCompile Include="..\test_delegate.cpp" />
<ClCompile Include="..\test_delegate_service.cpp" />
<ClCompile Include="..\test_fixed_sized_memory_block_allocator.cpp" />
<ClCompile Include="..\test_flags.cpp" />
<ClCompile Include="..\test_format_spec.cpp" />
<ClCompile Include="..\test_forward_list_shared_pool.cpp" />

View File

@ -1478,6 +1478,9 @@
<ClCompile Include="..\test_shared_message.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_fixed_sized_memory_block_allocator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">