mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Initial design
This commit is contained in:
parent
e323f2267f
commit
f3ace52884
@ -211,8 +211,10 @@ namespace etl
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
fsm(etl::message_router_id_t id)
|
||||
: imessage_router(id),
|
||||
p_state(ETL_NULLPTR)
|
||||
: imessage_router(id)
|
||||
, p_state(ETL_NULLPTR)
|
||||
, state_list(ETL_NULLPTR)
|
||||
, number_of_states(0U)
|
||||
{
|
||||
}
|
||||
|
||||
@ -434,7 +436,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -499,7 +501,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -563,7 +565,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -626,7 +628,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -687,7 +689,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -747,7 +749,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -806,7 +808,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -864,7 +866,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -920,7 +922,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -975,7 +977,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1029,7 +1031,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1082,7 +1084,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1133,7 +1135,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1183,7 +1185,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1232,7 +1234,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
@ -1280,7 +1282,7 @@ namespace etl
|
||||
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t new_state_id;
|
||||
etl::message_id_t event_id = message.message_id;
|
||||
etl::message_id_t event_id = message.get_message_id();
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
|
||||
@ -454,7 +454,7 @@ namespace etl
|
||||
cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" etl::fsm_state_id_t new_state_id;")
|
||||
cog.outl(" etl::message_id_t event_id = message.message_id;")
|
||||
cog.outl(" etl::message_id_t event_id = message.get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (event_id)")
|
||||
cog.outl(" {")
|
||||
@ -531,7 +531,7 @@ namespace etl
|
||||
cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" etl::fsm_state_id_t new_state_id;")
|
||||
cog.outl(" etl::message_id_t event_id = message.message_id;")
|
||||
cog.outl(" etl::message_id_t event_id = message.get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (event_id)")
|
||||
cog.outl(" {")
|
||||
|
||||
@ -217,7 +217,7 @@ namespace etl
|
||||
cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)")
|
||||
cog.outl(" pmsg->~imessage();")
|
||||
cog.outl("#else")
|
||||
cog.outl(" size_t id = pmsg->message_id;")
|
||||
cog.outl(" size_t id = pmsg->get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
@ -232,7 +232,7 @@ namespace etl
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.message_id;")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
cog.outl(" void* p = data;")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
@ -247,7 +247,7 @@ namespace etl
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(etl::imessage&& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.message_id;")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
cog.outl(" void* p = data;")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
@ -416,7 +416,7 @@ namespace etl
|
||||
cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)")
|
||||
cog.outl(" pmsg->~imessage();")
|
||||
cog.outl("#else")
|
||||
cog.outl(" size_t id = pmsg->message_id;")
|
||||
cog.outl(" size_t id = pmsg->get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
@ -431,7 +431,7 @@ namespace etl
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.message_id;")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
cog.outl(" void* p = data;")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
@ -446,7 +446,7 @@ namespace etl
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(etl::imessage&& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.message_id;")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
cog.outl(" void* p = data;")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
|
||||
@ -126,7 +126,7 @@ namespace etl
|
||||
//********************************************
|
||||
bool accepts(const etl::imessage& msg) const
|
||||
{
|
||||
return accepts(msg.message_id);
|
||||
return accepts(msg.get_message_id());
|
||||
}
|
||||
|
||||
//********************************************
|
||||
@ -376,7 +376,7 @@ namespace etl
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const etl::message_id_t id = msg.message_id;")
|
||||
cog.outl(" const etl::message_id_t id = msg.get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
@ -509,7 +509,7 @@ namespace etl
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.message_id;")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
cog.outl("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
|
||||
@ -369,7 +369,7 @@ namespace etl
|
||||
/// Destroys the object.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
bool destroy(const T* const p)
|
||||
void destroy(const T* const p)
|
||||
{
|
||||
/*[[[cog
|
||||
import cog
|
||||
@ -395,12 +395,10 @@ namespace etl
|
||||
if (pool.is_in_pool(vp))
|
||||
{
|
||||
pool.release(vp);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(variant_pool_did_not_create));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
209
include/etl/generic_pool.h
Normal file
209
include/etl/generic_pool.h
Normal file
@ -0,0 +1,209 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 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_GENERIC_POOL_INCLUDED
|
||||
#define ETL_GENERIC_POOL_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "ipool.h"
|
||||
#include "type_traits.h"
|
||||
#include "static_assert.h"
|
||||
#include "alignment.h"
|
||||
|
||||
#define ETL_POOL_CPP03_CODE 0
|
||||
|
||||
//*****************************************************************************
|
||||
///\defgroup pool pool
|
||||
/// A fixed capacity pool.
|
||||
///\ingroup containers
|
||||
//*****************************************************************************
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*************************************************************************
|
||||
/// A templated abstract pool implementation that uses a fixed size pool.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
template <const size_t TYPE_SIZE_, const size_t ALIGNMENT_, const size_t SIZE_>
|
||||
class generic_pool : public etl::ipool
|
||||
{
|
||||
public:
|
||||
|
||||
static const size_t SIZE = SIZE_;
|
||||
static const size_t ALIGNMENT = ALIGNMENT_;
|
||||
static const size_t TYPE_SIZE = TYPE_SIZE_;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
generic_pool()
|
||||
: etl::ipool(reinterpret_cast<char*>(&buffer[0]), ELEMENT_SIZE, SIZE)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
/// Static asserts if the specified type is too large for the pool.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* allocate()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::allocate<U>();
|
||||
}
|
||||
|
||||
#if !ETL_CPP11_SUPPORTED || ETL_POOL_CPP03_CODE || defined(ETL_STLPORT)
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* create()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1>
|
||||
U* create(const T1& value1)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 2 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2>
|
||||
U* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 3 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 4 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3, typename T4>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3, value4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename U, typename... Args>
|
||||
U* create(Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(etl::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Releases the object.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void release(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
ipool::release(p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void destroy(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
ipool::destroy(p_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The pool element.
|
||||
union Element
|
||||
{
|
||||
char* next; ///< Pointer to the next free element.
|
||||
char value[TYPE_SIZE_]; ///< Storage for value type.
|
||||
typename etl::type_with_alignment<ALIGNMENT_>::type dummy; ///< Dummy item to get correct alignment.
|
||||
};
|
||||
|
||||
///< The memory for the pool of objects.
|
||||
typename etl::aligned_storage<sizeof(Element), etl::alignment_of<Element>::value>::type buffer[SIZE];
|
||||
|
||||
static ETL_CONST_OR_CONSTEXPR uint32_t ELEMENT_SIZE = sizeof(Element);
|
||||
|
||||
// Should not be copied.
|
||||
generic_pool(const generic_pool&);
|
||||
generic_pool& operator =(const generic_pool&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
495
include/etl/ipool.h
Normal file
495
include/etl/ipool.h
Normal file
@ -0,0 +1,495 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 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_IPOOL_INCLUDED
|
||||
#define ETL_IPOOL_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "static_assert.h"
|
||||
#include "utility.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "11"
|
||||
|
||||
#define ETL_POOL_CPP03_CODE 0
|
||||
|
||||
//*****************************************************************************
|
||||
///\defgroup pool pool
|
||||
/// A fixed capacity pool.
|
||||
///\ingroup containers
|
||||
//*****************************************************************************
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
explicit pool_no_allocation(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_FILE"A"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an object is released which does not belong to the pool.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_object_not_in_pool : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_object_not_in_pool(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:not in pool", ETL_FILE"B"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an the type requested is larger than the element size.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_element_size : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_element_size(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:element size", ETL_FILE"C"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base implementation of a pool.
|
||||
/// Implements the imemory_block_pool interface.
|
||||
//***************************************************************************
|
||||
class ipool : public imemory_block_pool
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Implementation of the low level imemory_block_pool interface.
|
||||
//*************************************************************************
|
||||
void* allocate_memory_block(size_t require_size) ETL_OVERRIDE
|
||||
{
|
||||
return allocate<void*>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Implementation of the low level imemory_block_pool interface.
|
||||
//*************************************************************************
|
||||
void release_memory_block(const void* const ptr) ETL_OVERRIDE
|
||||
{
|
||||
release(ptr);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Implementation of the low level imemory_block_pool interface.
|
||||
//*************************************************************************
|
||||
size_t get_memory_block_size() ETL_OVERRIDE
|
||||
{
|
||||
return ITEM_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* allocate()
|
||||
{
|
||||
if (sizeof(T) > ITEM_SIZE)
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::pool_element_size));
|
||||
}
|
||||
|
||||
return reinterpret_cast<T*>(allocate_item());
|
||||
}
|
||||
|
||||
#if !ETL_CPP11_SUPPORTED || ETL_POOL_CPP03_CODE || defined(ETL_STLPORT)
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* create()
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T, typename T1>
|
||||
T* create(const T1& value1)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2>
|
||||
T* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2, typename T3>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2, value3);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2, typename T3, typename T4>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2, value3, value4);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename T, typename... Args>
|
||||
T* create(Args&&... args)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(etl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// If asserts or exceptions are enabled and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// Undefined behaviour if p_object is not a 'T' or derived from 'T'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
void destroy(const T* const p_object)
|
||||
{
|
||||
// Does it belong to us?
|
||||
if (is_in_pool(p_object))
|
||||
{
|
||||
p_object->~T();
|
||||
release_item((char*)p_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ALWAYS_ASSERT(ETL_ERROR(pool_object_not_in_pool));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an object in the pool.
|
||||
/// If asserts or exceptions are enabled and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const void* const p_object)
|
||||
{
|
||||
// Does it belong to us?
|
||||
if (is_in_pool(p_object))
|
||||
{
|
||||
release_item((char*)p_object);
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ALWAYS_ASSERT(ETL_ERROR(pool_object_not_in_pool));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release all objects in the pool.
|
||||
//*************************************************************************
|
||||
void release_all()
|
||||
{
|
||||
items_allocated = 0;
|
||||
items_initialised = 0;
|
||||
p_next = p_buffer;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check to see if the object belongs to the pool.
|
||||
/// \param p_object A pointer to the object to be checked.
|
||||
/// \return <b>true<\b> if it does, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool is_in_pool(const void* p_object) const
|
||||
{
|
||||
return is_item_in_pool((const char*)p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
size_t max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
size_t capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return MAX_SIZE - items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of allocated items in the pool.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
return items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no allocated items in the pool.
|
||||
/// \return <b>true</b> if there are none allocated.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return items_allocated == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return items_allocated == MAX_SIZE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
ipool(char* p_buffer_, uint32_t item_size_, uint32_t max_size_)
|
||||
: p_buffer(p_buffer_),
|
||||
p_next(p_buffer_),
|
||||
items_allocated(0),
|
||||
items_initialised(0),
|
||||
ITEM_SIZE(item_size_),
|
||||
MAX_SIZE(max_size_)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an item from the pool.
|
||||
//*************************************************************************
|
||||
char* allocate_item()
|
||||
{
|
||||
char* p_value = ETL_NULLPTR;
|
||||
|
||||
// Any free space left?
|
||||
if (items_allocated < MAX_SIZE)
|
||||
{
|
||||
// Initialise another one if necessary.
|
||||
if (items_initialised < MAX_SIZE)
|
||||
{
|
||||
char* p = p_buffer + (items_initialised * ITEM_SIZE);
|
||||
char* np = p + ITEM_SIZE;
|
||||
*reinterpret_cast<char**>(p) = np;
|
||||
++items_initialised;
|
||||
}
|
||||
|
||||
// Get the address of new allocated item.
|
||||
p_value = p_next;
|
||||
|
||||
++items_allocated;
|
||||
if (items_allocated != MAX_SIZE)
|
||||
{
|
||||
// Set up the pointer to the next free item
|
||||
p_next = *reinterpret_cast<char**>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more left!
|
||||
p_next = ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(pool_no_allocation));
|
||||
}
|
||||
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an item back to the pool.
|
||||
//*************************************************************************
|
||||
void release_item(char* p_value)
|
||||
{
|
||||
if (p_next != ETL_NULLPTR)
|
||||
{
|
||||
// Point it to the current free item.
|
||||
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the only free item.
|
||||
*((uintptr_t*)p_value) = 0;
|
||||
}
|
||||
|
||||
p_next = p_value;
|
||||
|
||||
--items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the item belongs to this pool.
|
||||
//*************************************************************************
|
||||
bool is_item_in_pool(const char* p) const
|
||||
{
|
||||
// Within the range of the buffer?
|
||||
intptr_t distance = p - p_buffer;
|
||||
bool is_within_range = (distance >= 0) && (distance <= intptr_t((ITEM_SIZE * MAX_SIZE) - ITEM_SIZE));
|
||||
|
||||
// Modulus and division can be slow on some architectures, so only do this in debug.
|
||||
#if defined(ETL_DEBUG)
|
||||
// Is the address on a valid object boundary?
|
||||
bool is_valid_address = ((distance % ITEM_SIZE) == 0);
|
||||
#else
|
||||
bool is_valid_address = true;
|
||||
#endif
|
||||
|
||||
return is_within_range && is_valid_address;
|
||||
}
|
||||
|
||||
// Disable copy construction and assignment.
|
||||
ipool(const ipool&);
|
||||
ipool& operator =(const ipool&);
|
||||
|
||||
char* p_buffer;
|
||||
char* p_next;
|
||||
|
||||
uint32_t items_allocated; ///< The number of items allocated.
|
||||
uint32_t items_initialised; ///< The number of items initialised.
|
||||
|
||||
const uint32_t ITEM_SIZE; ///< The size of allocated items.
|
||||
const uint32_t MAX_SIZE; ///< The maximum number of objects that can be allocated.
|
||||
|
||||
//*************************************************************************
|
||||
/// Destructor.
|
||||
//*************************************************************************
|
||||
#if defined(ETL_POLYMORPHIC_POOL) || defined(ETL_POLYMORPHIC_CONTAINERS)
|
||||
public:
|
||||
virtual ~ipool()
|
||||
{
|
||||
}
|
||||
#else
|
||||
protected:
|
||||
~ipool()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
|
||||
@ -40,7 +40,6 @@ SOFTWARE.
|
||||
#include "algorithm.h"
|
||||
#include "iterator.h"
|
||||
#include "functional.h"
|
||||
|
||||
#include "container.h"
|
||||
#include "pool.h"
|
||||
#include "exception.h"
|
||||
@ -51,6 +50,7 @@ SOFTWARE.
|
||||
#include "algorithm.h"
|
||||
#include "memory.h"
|
||||
#include "iterator.h"
|
||||
#include "parameter_type.h"
|
||||
|
||||
#if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL)
|
||||
#include <initializer_list>
|
||||
|
||||
@ -1900,6 +1900,16 @@ namespace etl
|
||||
memory_clear(static_cast<volatile T&>(*this));
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The interface for a memory block pool.
|
||||
//*************************************************************************
|
||||
struct imemory_block_pool
|
||||
{
|
||||
virtual void* allocate_memory_block(size_t required_size) = 0;
|
||||
virtual void release_memory_block(const void* const) = 0;
|
||||
virtual size_t get_memory_block_size() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,7 @@ SOFTWARE.
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "message_types.h"
|
||||
#include "reference_counted_object.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "38"
|
||||
@ -68,39 +69,90 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
imessage(etl::message_id_t id)
|
||||
: message_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
const etl::message_id_t message_id;
|
||||
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
virtual ~imessage()
|
||||
{
|
||||
}
|
||||
#else
|
||||
~imessage()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
ETL_NODISCARD virtual etl::message_id_t get_message_id() const ETL_NOEXCEPT = 0;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <const etl::message_id_t ID_>
|
||||
class message : public imessage
|
||||
class ireference_counted_message : public etl::imessage, public etl::ireference_counted_object
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <typename TCounter>
|
||||
class reference_counted_message : public etl::ireference_counted_message
|
||||
{
|
||||
private:
|
||||
|
||||
//***************************************************************************
|
||||
void set_reference_count(uint32_t value) ETL_OVERRIDE
|
||||
{
|
||||
reference_count = value;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
void increment_reference_count() ETL_OVERRIDE
|
||||
{
|
||||
++reference_count;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD uint32_t decrement_reference_count() ETL_OVERRIDE
|
||||
{
|
||||
return uint32_t(--reference_count);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD uint32_t get_reference_count() const ETL_OVERRIDE
|
||||
{
|
||||
return uint32_t(reference_count);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// The reference counter.
|
||||
TCounter reference_count;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Reference counted message.
|
||||
//***************************************************************************
|
||||
template <etl::message_id_t ID_, typename TCounter = void>
|
||||
class message : public reference_counted_message<TCounter>
|
||||
{
|
||||
public:
|
||||
|
||||
message()
|
||||
: imessage(ID_)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ID = ID_
|
||||
};
|
||||
|
||||
ETL_NODISCARD etl::message_id_t get_message_id() const ETL_NOEXCEPT
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Non-reference counted message.
|
||||
//***************************************************************************
|
||||
template <etl::message_id_t ID_>
|
||||
class message<ID_, void> : public imessage
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
ID = ID_
|
||||
};
|
||||
|
||||
ETL_NODISCARD etl::message_id_t get_message_id() const ETL_NOEXCEPT
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -187,7 +187,7 @@ namespace etl
|
||||
{
|
||||
etl::imessage_router& router = **irouter;
|
||||
|
||||
if (router.accepts(message.message_id))
|
||||
if (router.accepts(message.get_message_id()))
|
||||
{
|
||||
router.receive(source, message);
|
||||
}
|
||||
@ -213,7 +213,7 @@ namespace etl
|
||||
// Call all of them.
|
||||
while (range.first != range.second)
|
||||
{
|
||||
if ((*(range.first))->accepts(message.message_id))
|
||||
if ((*(range.first))->accepts(message.get_message_id()))
|
||||
{
|
||||
(*(range.first))->receive(source, message);
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -219,7 +219,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -248,7 +248,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -403,7 +403,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -431,7 +431,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -459,7 +459,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -613,7 +613,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -640,7 +640,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -667,7 +667,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -820,7 +820,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -846,7 +846,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -872,7 +872,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1023,7 +1023,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1048,7 +1048,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1073,7 +1073,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1223,7 +1223,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1247,7 +1247,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1271,7 +1271,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1420,7 +1420,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1443,7 +1443,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1466,7 +1466,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1614,7 +1614,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1636,7 +1636,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1658,7 +1658,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1804,7 +1804,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1825,7 +1825,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1846,7 +1846,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -1991,7 +1991,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2011,7 +2011,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2031,7 +2031,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2175,7 +2175,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2194,7 +2194,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2213,7 +2213,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2356,7 +2356,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2374,7 +2374,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2392,7 +2392,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2533,7 +2533,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2550,7 +2550,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2567,7 +2567,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2707,7 +2707,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2723,7 +2723,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2739,7 +2739,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2878,7 +2878,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -2893,7 +2893,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -2908,7 +2908,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -3046,7 +3046,7 @@ namespace etl
|
||||
#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
size_t id = pmsg->message_id;
|
||||
size_t id = pmsg->get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -3060,7 +3060,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
@ -3074,7 +3074,7 @@ namespace etl
|
||||
//********************************************
|
||||
void add_new_message(etl::imessage&& msg)
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
void* p = data;
|
||||
|
||||
switch (id)
|
||||
|
||||
258
include/etl/message_pool.h
Normal file
258
include/etl/message_pool.h
Normal file
@ -0,0 +1,258 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_MESSAGE_POOL_INCLUDED
|
||||
#define ETL_MESSAGE_POOL_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "message.h"
|
||||
#include "static_assert.h"
|
||||
#include "error_handler.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
class message_pool_allocation_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_pool_allocation_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
class message_pool_allocation_failure : etl::message_pool_allocation_exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_pool_allocation_failure(string_type file_name_, numeric_type line_number_)
|
||||
: message_pool_allocation_exception(ETL_ERROR_TEXT("message_pool:allocation failure", ETL_FILE"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///
|
||||
//***************************************************************************
|
||||
class message_pool
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
message_pool(imemory_block_pool& memory_block_pool_)
|
||||
: memory_block_pool(memory_block_pool_)
|
||||
{
|
||||
}
|
||||
|
||||
#if ETL_CPP11_SUPPORTED && !defined(ETL_MESSAGE_POOL_FORCE_CPP03)
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename... TArgs>
|
||||
TMessage* create(TArgs&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage(etl::forward<Args>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ALWAYS_ASSERT(ETL_ERROR(etl::message_pool_allocation_failure));
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool. No parameters.
|
||||
//*************************************************************************
|
||||
template <typename TMessage>
|
||||
TMessage* create()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool. One parameter.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename T1>
|
||||
TMessage* create(const T1& t1)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_base_of<etl::imessage, TMessage>::value, "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage(t1);
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool. Two parameters.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename T1, typename T2>
|
||||
TMessage* create(const T1& t1, const T2& t2)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_base_of<etl::imessage, TMessage>::value, "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage(t1, t2);
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool. Three parameters.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename T1, typename T2, typename T3>
|
||||
TMessage* create(const T1& t1, const T2& t2, const T3& t3)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_base_of<etl::imessage, TMessage>::value, "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage(t1, t2, t3);
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Create a message from the pool. Four parameters.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename T1, typename T2, typename T3, typename T4>
|
||||
TMessage* create(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_base_of<etl::imessage, TMessage>::value, "Not a message type");
|
||||
|
||||
void* p = ETL_NULLPTR;
|
||||
|
||||
if (sizeof(TMessage) <= memory_block_pool.get_memory_block_size())
|
||||
{
|
||||
p = memory_block_pool.allocate_memory_block(sizeof(TMessage));
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) TMessage(t1, t2, t3, t4);
|
||||
}
|
||||
}
|
||||
|
||||
return reinterpret_cast<TMessage*>(p)
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destruct a message and send it back to the pool.
|
||||
//*************************************************************************
|
||||
void destroy(const etl::imessage* const pmsg)
|
||||
{
|
||||
pmsg->~imessage();
|
||||
memory_block_pool.release_memory_block(pmsg);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Destruct a message and send it back to the pool.
|
||||
//*************************************************************************
|
||||
void destroy(const etl::imessage& msg)
|
||||
{
|
||||
destroy(&msg);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// The raw memory block pool.
|
||||
imemory_block_pool& memory_block_pool;
|
||||
|
||||
// Should not be copied.
|
||||
message_pool(const message_pool&) ETL_DELETE;
|
||||
message_pool& operator =(const message_pool&) ETL_DELETE;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
|
||||
@ -114,7 +114,7 @@ namespace etl
|
||||
//********************************************
|
||||
bool accepts(const etl::imessage& msg) const
|
||||
{
|
||||
return accepts(msg.message_id);
|
||||
return accepts(msg.get_message_id());
|
||||
}
|
||||
|
||||
//********************************************
|
||||
@ -351,7 +351,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const etl::message_id_t id = msg.message_id;
|
||||
const etl::message_id_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -467,7 +467,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -582,7 +582,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -696,7 +696,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -808,7 +808,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -919,7 +919,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1029,7 +1029,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1138,7 +1138,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1245,7 +1245,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1351,7 +1351,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1455,7 +1455,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1558,7 +1558,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1659,7 +1659,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1759,7 +1759,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1858,7 +1858,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -1956,7 +1956,7 @@ namespace etl
|
||||
//**********************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE
|
||||
{
|
||||
const size_t id = msg.message_id;
|
||||
const size_t id = msg.get_message_id();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
|
||||
@ -32,24 +32,8 @@ SOFTWARE.
|
||||
#define ETL_POOL_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "iterator.h"
|
||||
#include "utility.h"
|
||||
#include "error_handler.h"
|
||||
#include "alignment.h"
|
||||
#include "array.h"
|
||||
#include "container.h"
|
||||
#include "integral_limits.h"
|
||||
#include "nullptr.h"
|
||||
#include "alignment.h"
|
||||
#include "generic_pool.h"
|
||||
#include "static_assert.h"
|
||||
#include "algorithm.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "11"
|
||||
|
||||
#define ETL_POOL_CPP03_CODE 0
|
||||
|
||||
@ -61,553 +45,6 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
explicit pool_no_allocation(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_FILE"A"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an object is released which does not belong to the pool.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_object_not_in_pool : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_object_not_in_pool(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:not in pool", ETL_FILE"B"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an the type requested is larger than the element size.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_element_size : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_element_size(string_type file_name_, numeric_type line_number_)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:element size", ETL_FILE"C"), file_name_, line_number_)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class ipool
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* allocate()
|
||||
{
|
||||
if (sizeof(T) > ITEM_SIZE)
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::pool_element_size));
|
||||
}
|
||||
|
||||
return reinterpret_cast<T*>(allocate_item());
|
||||
}
|
||||
|
||||
#if !ETL_CPP11_SUPPORTED || ETL_POOL_CPP03_CODE || defined(ETL_STLPORT)
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* create()
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename T, typename T1>
|
||||
T* create(const T1& value1)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2>
|
||||
T* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2, typename T3>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2, value3);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename T2, typename T3, typename T4>
|
||||
T* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(value1, value2, value3, value4);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename T, typename... Args>
|
||||
T* create(Args&&... args)
|
||||
{
|
||||
T* p = allocate<T>();
|
||||
|
||||
if (p)
|
||||
{
|
||||
::new (p) T(etl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'T'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
void destroy(const T* const p_object)
|
||||
{
|
||||
if (sizeof(T) > ITEM_SIZE)
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::pool_element_size));
|
||||
}
|
||||
|
||||
p_object->~T();
|
||||
release(p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an object in the pool.
|
||||
/// If asserts or exceptions are enabled and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const void* const p_object)
|
||||
{
|
||||
release_item((char*)p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release all objects in the pool.
|
||||
//*************************************************************************
|
||||
void release_all()
|
||||
{
|
||||
items_allocated = 0;
|
||||
items_initialised = 0;
|
||||
p_next = p_buffer;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check to see if the object belongs to the pool.
|
||||
/// \param p_object A pointer to the object to be checked.
|
||||
/// \return <b>true<\b> if it does, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
//template <typename T>
|
||||
bool is_in_pool(const void* p_object) const
|
||||
{
|
||||
return is_item_in_pool((const char*)p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
size_t max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
size_t capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return MAX_SIZE - items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of allocated items in the pool.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
return items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no allocated items in the pool.
|
||||
/// \return <b>true</b> if there are none allocated.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return items_allocated == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return items_allocated == MAX_SIZE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
ipool(char* p_buffer_, uint32_t item_size_, uint32_t max_size_)
|
||||
: p_buffer(p_buffer_),
|
||||
p_next(p_buffer_),
|
||||
items_allocated(0),
|
||||
items_initialised(0),
|
||||
ITEM_SIZE(item_size_),
|
||||
MAX_SIZE(max_size_)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an item from the pool.
|
||||
//*************************************************************************
|
||||
char* allocate_item()
|
||||
{
|
||||
char* p_value = ETL_NULLPTR;
|
||||
|
||||
// Any free space left?
|
||||
if (items_allocated < MAX_SIZE)
|
||||
{
|
||||
// Initialise another one if necessary.
|
||||
if (items_initialised < MAX_SIZE)
|
||||
{
|
||||
char* p = p_buffer + (items_initialised * ITEM_SIZE);
|
||||
char* np = p + ITEM_SIZE;
|
||||
*reinterpret_cast<char**>(p) = np;
|
||||
++items_initialised;
|
||||
}
|
||||
|
||||
// Get the address of new allocated item.
|
||||
p_value = p_next;
|
||||
|
||||
++items_allocated;
|
||||
if (items_allocated != MAX_SIZE)
|
||||
{
|
||||
// Set up the pointer to the next free item
|
||||
p_next = *reinterpret_cast<char**>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more left!
|
||||
p_next = ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(pool_no_allocation));
|
||||
}
|
||||
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an item back to the pool.
|
||||
//*************************************************************************
|
||||
void release_item(char* p_value)
|
||||
{
|
||||
// Does it belong to us?
|
||||
ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool));
|
||||
|
||||
if (p_next != ETL_NULLPTR)
|
||||
{
|
||||
// Point it to the current free item.
|
||||
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the only free item.
|
||||
*((uintptr_t*)p_value) = 0;
|
||||
}
|
||||
|
||||
p_next = p_value;
|
||||
|
||||
--items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the item belongs to this pool.
|
||||
//*************************************************************************
|
||||
bool is_item_in_pool(const char* p) const
|
||||
{
|
||||
// Within the range of the buffer?
|
||||
intptr_t distance = p - p_buffer;
|
||||
bool is_within_range = (distance >= 0) && (distance <= intptr_t((ITEM_SIZE * MAX_SIZE) - ITEM_SIZE));
|
||||
|
||||
// Modulus and division can be slow on some architectures, so only do this in debug.
|
||||
#if defined(ETL_DEBUG)
|
||||
// Is the address on a valid object boundary?
|
||||
bool is_valid_address = ((distance % ITEM_SIZE) == 0);
|
||||
#else
|
||||
bool is_valid_address = true;
|
||||
#endif
|
||||
|
||||
return is_within_range && is_valid_address;
|
||||
}
|
||||
|
||||
// Disable copy construction and assignment.
|
||||
ipool(const ipool&);
|
||||
ipool& operator =(const ipool&);
|
||||
|
||||
char* p_buffer;
|
||||
char* p_next;
|
||||
|
||||
uint32_t items_allocated; ///< The number of items allocated.
|
||||
uint32_t items_initialised; ///< The number of items initialised.
|
||||
|
||||
const uint32_t ITEM_SIZE; ///< The size of allocated items.
|
||||
const uint32_t MAX_SIZE; ///< The maximum number of objects that can be allocated.
|
||||
|
||||
//*************************************************************************
|
||||
/// Destructor.
|
||||
//*************************************************************************
|
||||
#if defined(ETL_POLYMORPHIC_POOL) || defined(ETL_POLYMORPHIC_CONTAINERS)
|
||||
public:
|
||||
virtual ~ipool()
|
||||
{
|
||||
}
|
||||
#else
|
||||
protected:
|
||||
~ipool()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// A templated abstract pool implementation that uses a fixed size pool.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
template <const size_t TYPE_SIZE_, const size_t ALIGNMENT_, const size_t SIZE_>
|
||||
class generic_pool : public etl::ipool
|
||||
{
|
||||
public:
|
||||
|
||||
static const size_t SIZE = SIZE_;
|
||||
static const size_t ALIGNMENT = ALIGNMENT_;
|
||||
static const size_t TYPE_SIZE = TYPE_SIZE_;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
generic_pool()
|
||||
: etl::ipool(reinterpret_cast<char*>(&buffer[0]), ELEMENT_SIZE, SIZE)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
/// Static asserts if the specified type is too large for the pool.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* allocate()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::allocate<U>();
|
||||
}
|
||||
|
||||
#if !ETL_CPP11_SUPPORTED || ETL_POOL_CPP03_CODE || defined(ETL_STLPORT)
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with default.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
U* create()
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 1 parameter.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1>
|
||||
U* create(const T1& value1)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 2 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2>
|
||||
U* create(const T1& value1, const T2& value2)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 3 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate storage for an object from the pool and create with 4 parameters.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a null pointer is returned.
|
||||
//*************************************************************************
|
||||
template <typename U, typename T1, typename T2, typename T3, typename T4>
|
||||
U* create(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(value1, value2, value3, value4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplace with variadic constructor parameters.
|
||||
//*************************************************************************
|
||||
template <typename U, typename... Args>
|
||||
U* create(Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
return ipool::create<U>(etl::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void destroy(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::alignment_of<U>::value <= ALIGNMENT_, "Type has incompatible alignment");
|
||||
ETL_STATIC_ASSERT(sizeof(U) <= TYPE_SIZE, "Type too large for pool");
|
||||
p_object->~U();
|
||||
ipool::release(p_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The pool element.
|
||||
union Element
|
||||
{
|
||||
char* next; ///< Pointer to the next free element.
|
||||
char value[TYPE_SIZE_]; ///< Storage for value type.
|
||||
typename etl::type_with_alignment<ALIGNMENT_>::type dummy; ///< Dummy item to get correct alignment.
|
||||
};
|
||||
|
||||
///< The memory for the pool of objects.
|
||||
typename etl::aligned_storage<sizeof(Element), etl::alignment_of<Element>::value>::type buffer[SIZE];
|
||||
|
||||
static const uint32_t ELEMENT_SIZE = sizeof(Element);
|
||||
|
||||
// Should not be copied.
|
||||
generic_pool(const generic_pool&);
|
||||
generic_pool& operator =(const generic_pool&);
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// A templated pool implementation that uses a fixed size pool.
|
||||
@ -712,17 +149,28 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Releases the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U' object derived from 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void release(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<U, T>::value), "Pool does not contain this type");
|
||||
base_t::template release(p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Destroys the object.
|
||||
/// Undefined behaviour if the pool does not contain a 'U'.
|
||||
/// Undefined behaviour if the pool does not contain a 'U' object derived from 'U'.
|
||||
/// \param p_object A pointer to the object to be destroyed.
|
||||
//*************************************************************************
|
||||
template <typename U>
|
||||
void destroy(const U* const p_object)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<U, T>::value), "Pool does not contain this type");
|
||||
p_object->~U();
|
||||
base_t::release(p_object);
|
||||
base_t::template destroy(p_object);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -733,7 +181,5 @@ namespace etl
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
51
include/etl/reference_counted_object.h
Normal file
51
include/etl/reference_counted_object.h
Normal file
@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_REFERENCE_COUNTED_OBJECT_INCLUDED
|
||||
#define ETL_REFERENCE_COUNTED_OBJECT_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
class ireference_counted_object
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ireference_counted_object() {};
|
||||
virtual void set_reference_count(uint32_t value) = 0;
|
||||
virtual void increment_reference_count() = 0;
|
||||
ETL_NODISCARD virtual uint32_t decrement_reference_count() = 0;
|
||||
ETL_NODISCARD virtual uint32_t get_reference_count() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
137
include/etl/shared_message.h
Normal file
137
include/etl/shared_message.h
Normal file
@ -0,0 +1,137 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_SHARED_MESSAGE_INCLUDED
|
||||
#define ETL_SHARED_MESSAGE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "message_pool.h"
|
||||
#include "message.h"
|
||||
|
||||
//*****************************************************************************
|
||||
/// A wrapper for reference countable messages.
|
||||
/// Contains pointers to a pool owner and a message defined with a ref count type.
|
||||
/// See etl::message template.
|
||||
//*****************************************************************************
|
||||
namespace etl
|
||||
{
|
||||
class shared_message
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
/// \param owner_ A reference to the owner pool.
|
||||
/// \param pmessage A reference to the message allocated from the pool.
|
||||
//*************************************************************************
|
||||
shared_message(etl::message_pool& owner_, etl::ireference_counted_message& message_)
|
||||
: p_message_owner(&owner_)
|
||||
, p_message(&message_)
|
||||
{
|
||||
p_message->set_reference_count(1U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor
|
||||
//*************************************************************************
|
||||
shared_message(const shared_message& other)
|
||||
: p_message_owner(other.p_message_owner)
|
||||
, p_message(other.p_message)
|
||||
{
|
||||
p_message->increment_reference_count();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy assignment operator
|
||||
//*************************************************************************
|
||||
shared_message& operator =(const shared_message& other)
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
// Deal with the current message.
|
||||
if (p_message->decrement_reference_count() == 0U)
|
||||
{
|
||||
p_message_owner->destroy(p_message);
|
||||
}
|
||||
|
||||
// Copy over the new one.
|
||||
p_message_owner = other.p_message_owner;
|
||||
p_message = other.p_message;
|
||||
p_message->increment_reference_count();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Destructor
|
||||
/// Returns the message back to the pool it it is the last copy.
|
||||
//*************************************************************************
|
||||
~shared_message()
|
||||
{
|
||||
if (p_message->decrement_reference_count() == 0U)
|
||||
{
|
||||
p_message_owner->destroy(p_message);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get a reference to the contained message.
|
||||
//*************************************************************************
|
||||
etl::imessage& get_message()
|
||||
{
|
||||
return *p_message;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get a const reference to the contained message.
|
||||
//*************************************************************************
|
||||
const etl::imessage& get_message() const
|
||||
{
|
||||
return *p_message;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the current reference count for this pool message.
|
||||
//*************************************************************************
|
||||
uint32_t get_reference_count() const
|
||||
{
|
||||
return p_message->get_reference_count();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
etl::message_pool* p_message_owner;
|
||||
etl::ireference_counted_message* p_message;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -54,55 +54,13 @@ SOFTWARE.
|
||||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "largest.h"
|
||||
#include "generic_pool.h"
|
||||
#include "type_traits.h"
|
||||
#include "alignment.h"
|
||||
#include "static_assert.h"
|
||||
#include "type_lookup.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "40"
|
||||
#include "largest.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
class variant_pool_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
variant_pool_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
class variant_pool_cannot_create : public etl::variant_pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
variant_pool_cannot_create(string_type file_name_, numeric_type line_number_)
|
||||
: variant_pool_exception(ETL_ERROR_TEXT("variant_pool:cannot create", ETL_FILE"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
class variant_pool_did_not_create : public etl::variant_pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
variant_pool_did_not_create(string_type file_name_, numeric_type line_number_)
|
||||
: variant_pool_exception(ETL_ERROR_TEXT("variant_pool:did not create", ETL_FILE"B"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <const size_t MAX_SIZE_,
|
||||
typename T1,
|
||||
@ -121,10 +79,16 @@ namespace etl
|
||||
typename T14 = void,
|
||||
typename T15 = void,
|
||||
typename T16 = void>
|
||||
class variant_pool
|
||||
class variant_pool : public etl::generic_pool<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
|
||||
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment,
|
||||
MAX_SIZE_>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef etl::generic_pool<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
|
||||
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment,
|
||||
MAX_SIZE_> base_t;
|
||||
|
||||
static const size_t MAX_SIZE = MAX_SIZE_;
|
||||
|
||||
//*************************************************************************
|
||||
@ -143,23 +107,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T();
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -170,23 +118,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T(p1);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>(p1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -197,23 +129,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>(p1, p2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -224,23 +140,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T(p1, p2, p3);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>(p1, p2, p3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -251,23 +151,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T(p1, p2, p3, p4);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>(p1, p2, p3, p4);
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
@ -278,23 +162,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
|
||||
|
||||
T* p = ETL_NULLPTR;
|
||||
|
||||
if (pool.full())
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
|
||||
}
|
||||
else
|
||||
{
|
||||
p = pool.template allocate<T>();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
new (p) T(etl::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return base_t::template create<T>(args...);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -302,40 +170,27 @@ namespace etl
|
||||
/// Destroys the object.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
bool destroy(const T* const p)
|
||||
void destroy(const T* const p)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value ||
|
||||
etl::is_base_of<T, T1>::value ||
|
||||
etl::is_base_of<T, T2>::value ||
|
||||
etl::is_base_of<T, T3>::value ||
|
||||
etl::is_base_of<T, T4>::value ||
|
||||
etl::is_base_of<T, T5>::value ||
|
||||
etl::is_base_of<T, T6>::value ||
|
||||
etl::is_base_of<T, T7>::value ||
|
||||
etl::is_base_of<T, T8>::value ||
|
||||
etl::is_base_of<T, T9>::value ||
|
||||
etl::is_base_of<T, T10>::value ||
|
||||
etl::is_base_of<T, T11>::value ||
|
||||
etl::is_base_of<T, T12>::value ||
|
||||
etl::is_base_of<T, T13>::value ||
|
||||
etl::is_base_of<T, T14>::value ||
|
||||
etl::is_base_of<T, T15>::value ||
|
||||
etl::is_base_of<T, T16>::value), "Invalid type");
|
||||
etl::is_base_of<T, T1>::value ||
|
||||
etl::is_base_of<T, T2>::value ||
|
||||
etl::is_base_of<T, T3>::value ||
|
||||
etl::is_base_of<T, T4>::value ||
|
||||
etl::is_base_of<T, T5>::value ||
|
||||
etl::is_base_of<T, T6>::value ||
|
||||
etl::is_base_of<T, T7>::value ||
|
||||
etl::is_base_of<T, T8>::value ||
|
||||
etl::is_base_of<T, T9>::value ||
|
||||
etl::is_base_of<T, T10>::value ||
|
||||
etl::is_base_of<T, T11>::value ||
|
||||
etl::is_base_of<T, T12>::value ||
|
||||
etl::is_base_of<T, T13>::value ||
|
||||
etl::is_base_of<T, T14>::value ||
|
||||
etl::is_base_of<T, T15>::value ||
|
||||
etl::is_base_of<T, T16>::value), "Invalid type");
|
||||
|
||||
p->~T();
|
||||
|
||||
void* vp = reinterpret_cast<char*>(const_cast<T*>(p));
|
||||
|
||||
if (pool.is_in_pool(vp))
|
||||
{
|
||||
pool.release(vp);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(variant_pool_did_not_create));
|
||||
return false;
|
||||
}
|
||||
base_t::destroy(p);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -346,52 +201,11 @@ namespace etl
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the variant_pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return pool.available();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of allocated items in the variant_pool.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
return pool.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no allocated items in the variant_pool.
|
||||
/// \return <b>true</b> if there are none allocated.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return pool.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the variant_pool.
|
||||
/// \return <b>true</b> if there are none free.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return pool.full();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
variant_pool(const variant_pool&);
|
||||
variant_pool& operator =(const variant_pool&);
|
||||
|
||||
// The pool.
|
||||
etl::generic_pool<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
|
||||
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment,
|
||||
MAX_SIZE> pool;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
|
||||
@ -199,9 +199,9 @@ namespace
|
||||
// The next line should result in a compile error.
|
||||
//Packet packet4(message4);
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(!static_cast<Message2&>(packet2.get()).moved);
|
||||
@ -225,8 +225,8 @@ namespace
|
||||
Packet packet1(message1);
|
||||
Packet packet2(std::move(message2));
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(static_cast<Message2&>(packet2.get()).moved);
|
||||
@ -253,9 +253,9 @@ namespace
|
||||
// The next line should result in a compile error.
|
||||
//Packet packet4(message4);
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().get_message_id());
|
||||
|
||||
CHECK_EQUAL(1, static_cast<const Message1&>(packet1.get()).x);
|
||||
CHECK_EQUAL(2.2, static_cast<const Message2&>(packet2.get()).x);
|
||||
@ -276,9 +276,9 @@ namespace
|
||||
|
||||
CHECK_THROW(Packet packet4(static_cast<etl::imessage&>(message4)), etl::unhandled_message_exception);
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE2, packet2.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE3, packet3.get().get_message_id());
|
||||
|
||||
CHECK_EQUAL(1, static_cast<Message1&>(packet1.get()).x);
|
||||
CHECK_EQUAL(2.2, static_cast<Message2&>(packet2.get()).x);
|
||||
@ -294,8 +294,8 @@ namespace
|
||||
Packet packet1(message1);
|
||||
Packet packet2(packet1);
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(!static_cast<Message1&>(packet2.get()).moved);
|
||||
@ -316,8 +316,8 @@ namespace
|
||||
Packet packet1(message1);
|
||||
Packet packet2(std::move(Packet(message1)));
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(static_cast<Message1&>(packet2.get()).moved);
|
||||
@ -340,8 +340,8 @@ namespace
|
||||
|
||||
packet2 = packet1;
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(!static_cast<Message1&>(packet2.get()).moved);
|
||||
@ -364,8 +364,8 @@ namespace
|
||||
|
||||
packet2 = std::move(packet1);
|
||||
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().message_id);
|
||||
CHECK_EQUAL(MESSAGE1, packet1.get().get_message_id());
|
||||
CHECK_EQUAL(MESSAGE1, packet2.get().get_message_id());
|
||||
|
||||
CHECK(!static_cast<Message1&>(packet1.get()).moved);
|
||||
CHECK(static_cast<Message1&>(packet2.get()).moved);
|
||||
|
||||
@ -416,19 +416,19 @@ namespace
|
||||
Router2 r2;
|
||||
|
||||
CHECK(r2.accepts(message1));
|
||||
CHECK(r2.accepts(message1.message_id));
|
||||
CHECK(r2.accepts(message1.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message2));
|
||||
CHECK(r2.accepts(message2.message_id));
|
||||
CHECK(r2.accepts(message2.get_message_id()));
|
||||
|
||||
CHECK(!r2.accepts(message3));
|
||||
CHECK(!r2.accepts(message3.message_id));
|
||||
CHECK(!r2.accepts(message3.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message4));
|
||||
CHECK(r2.accepts(message4.message_id));
|
||||
CHECK(r2.accepts(message4.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message5));
|
||||
CHECK(r2.accepts(message5.message_id));
|
||||
CHECK(r2.accepts(message5.get_message_id()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
127
test/test_pool_message.cpp
Normal file
127
test/test_pool_message.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/******************************************************************************
|
||||
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/pool.h"
|
||||
#include "etl/shared_message.h"
|
||||
#include "etl/message_pool.h"
|
||||
#include "etl/variant_pool.h"
|
||||
#include "etl/message.h"
|
||||
#include "etl/atomic.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Message1 : public etl::message<1, uint32_t>
|
||||
{
|
||||
};
|
||||
|
||||
SUITE(test_shared_message)
|
||||
{
|
||||
constexpr size_t POOL_SIZE = 2;
|
||||
|
||||
etl::variant_pool<POOL_SIZE, Message1> vpool;
|
||||
|
||||
etl::message_pool mp(vpool);
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_buffered)
|
||||
{
|
||||
etl::message_pool& mpool = mp;
|
||||
|
||||
{
|
||||
etl::shared_message* pbuffered_sm = nullptr;
|
||||
|
||||
{
|
||||
etl::shared_message sm(mpool, *mpool.create<Message1>());
|
||||
uint32_t count1 = sm.get_reference_count();
|
||||
|
||||
pbuffered_sm = new etl::shared_message(sm);
|
||||
//uint32_t count2 = sm.get_reference_count();
|
||||
//uint32_t count3 = pbuffered_sm->get_reference_count();
|
||||
|
||||
etl::shared_message sm2 = etl::shared_message(mpool, *mpool.create<Message1>());
|
||||
uint32_t count4 = sm2.get_reference_count();
|
||||
|
||||
pbuffered_sm = pbuffered_sm;
|
||||
}
|
||||
|
||||
size_t ps1 = vpool.size();
|
||||
|
||||
//{
|
||||
// uint32_t count = pbuffered_sm->get_reference_count();
|
||||
// etl::message_id_t id = pbuffered_sm->get_message().get_message_id();
|
||||
//}
|
||||
|
||||
size_t ps2 = vpool.size();
|
||||
|
||||
delete pbuffered_sm;
|
||||
}
|
||||
|
||||
size_t ps3 = vpool.size();
|
||||
|
||||
vpool.size();
|
||||
}
|
||||
}
|
||||
|
||||
////*************************************************************************
|
||||
//TEST(test_construct_and_destruct)
|
||||
//{
|
||||
// etl::pool<Message1, 2> pool;
|
||||
// etl::pool_chain<1> pool_chain;
|
||||
|
||||
// pool_chain.add(pool);
|
||||
|
||||
// etl::shared_message buffered_sm(pool_chain);
|
||||
|
||||
// {
|
||||
// etl::shared_message sm1(pool_chain, pool.create());
|
||||
// CHECK_EQUAL(1, sm1.get_reference_count());
|
||||
// CHECK_EQUAL(1, pool.size());
|
||||
// {
|
||||
// etl::shared_message sm2(sm1);
|
||||
// CHECK_EQUAL(1, sm1.get_reference_count());
|
||||
// CHECK_EQUAL(2, sm2.get_reference_count());
|
||||
// CHECK_EQUAL(1, pool.size());
|
||||
// {
|
||||
// etl::shared_message sm3(pool_chain);
|
||||
// sm3 = sm2;
|
||||
// CHECK_EQUAL(1, sm1.get_reference_count());
|
||||
// CHECK_EQUAL(2, sm2.get_reference_count());
|
||||
// CHECK_EQUAL(3, sm3.get_reference_count());
|
||||
// CHECK_EQUAL(1, pool.size());
|
||||
|
||||
// }
|
||||
// CHECK_EQUAL(1, pool.size());
|
||||
// }
|
||||
// CHECK_EQUAL(1, pool.size());
|
||||
// }
|
||||
// CHECK_EQUAL(0, pool.size());
|
||||
//}
|
||||
|
||||
}
|
||||
@ -202,7 +202,7 @@ namespace
|
||||
CHECK(!variant_pool.empty());
|
||||
CHECK(variant_pool.full());
|
||||
|
||||
CHECK_THROW(variant_pool.create<Derived1>(), etl::variant_pool_cannot_create);
|
||||
CHECK_THROW(variant_pool.create<Derived1>(), etl::pool_no_allocation);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -309,7 +309,7 @@ namespace
|
||||
CHECK_NO_THROW(variant_pool1.destroy(p));
|
||||
|
||||
p = variant_pool2.create<Derived1>();
|
||||
CHECK_THROW(variant_pool1.destroy(p), etl::variant_pool_did_not_create);
|
||||
CHECK_THROW(variant_pool1.destroy(p), etl::pool_object_not_in_pool);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1045,11 +1045,14 @@
|
||||
<ClInclude Include="..\..\include\etl\generators\type_select_generator.h" />
|
||||
<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\indirect_vector.h" />
|
||||
<ClInclude Include="..\..\include\etl\absolute.h" />
|
||||
<ClInclude Include="..\..\include\etl\ipool.h" />
|
||||
<ClInclude Include="..\..\include\etl\limits.h" />
|
||||
<ClInclude Include="..\..\include\etl\macros.h" />
|
||||
<ClInclude Include="..\..\include\etl\message_packet.h" />
|
||||
<ClInclude Include="..\..\include\etl\message_pool.h" />
|
||||
<ClInclude Include="..\..\include\etl\multi_array.h" />
|
||||
<ClInclude Include="..\..\include\etl\mutex\mutex_freertos.h" />
|
||||
<ClInclude Include="..\..\include\etl\negative.h" />
|
||||
@ -1079,6 +1082,7 @@
|
||||
<ClInclude Include="..\..\include\etl\profiles\ticc_no_stl.h" />
|
||||
<ClInclude Include="..\..\include\etl\queue_spsc_locked.h" />
|
||||
<ClInclude Include="..\..\include\etl\scaled_rounding.h" />
|
||||
<ClInclude Include="..\..\include\etl\shared_message.h" />
|
||||
<ClInclude Include="..\..\include\etl\span.h" />
|
||||
<ClInclude Include="..\..\include\etl\state_chart.h" />
|
||||
<ClInclude Include="..\..\include\etl\math_constants.h" />
|
||||
@ -1586,6 +1590,7 @@
|
||||
<ClCompile Include="..\test_parity_checksum.cpp" />
|
||||
<ClCompile Include="..\test_pearson.cpp" />
|
||||
<ClCompile Include="..\test_pool.cpp" />
|
||||
<ClCompile Include="..\test_pool_message.cpp" />
|
||||
<ClCompile Include="..\test_priority_queue.cpp" />
|
||||
<ClCompile Include="..\test_queue.cpp" />
|
||||
<ClCompile Include="..\test_queue_memory_model_small.cpp" />
|
||||
|
||||
@ -852,6 +852,18 @@
|
||||
<ClInclude Include="..\..\include\etl\generators\variant_pool_generator.h">
|
||||
<Filter>ETL\Containers\Generators</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\generic_pool.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\ipool.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\shared_message.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\message_pool.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\main.cpp">
|
||||
@ -1313,6 +1325,9 @@
|
||||
<ClCompile Include="..\test_span.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_pool_message.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\library.properties">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user