mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Add support for in-place instantiation of a shared message in the message pool (#854)
* #850 Fixed names according to Arduino's guidelines * #850 Fixed names according to Arduino's guidelines * Add support for in-place instantiation of a shared message in the message pool --------- Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com> Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
1e1ce38113
commit
268ca4e04b
@ -72,9 +72,12 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Constructor
|
||||
/// \param owner The message owner.
|
||||
/// \param args The constructor arguments.
|
||||
//***************************************************************************
|
||||
reference_counted_message(etl::ireference_counted_message_pool& owner_)
|
||||
: owner(owner_)
|
||||
template <typename... Args>
|
||||
reference_counted_message(etl::ireference_counted_message_pool& owner_, Args&&... args)
|
||||
: rc_object(etl::forward<Args>(args)...)
|
||||
, owner(owner_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +100,33 @@ namespace etl
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate a reference counted message from the pool.
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename... Args>
|
||||
etl::reference_counted_message<TMessage, TCounter>* allocate(const TMessage*, Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
|
||||
|
||||
typedef etl::reference_counted_message<TMessage, TCounter> rcm_t;
|
||||
typedef rcm_t* prcm_t;
|
||||
|
||||
prcm_t p = ETL_NULLPTR;
|
||||
|
||||
lock();
|
||||
p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
|
||||
unlock();
|
||||
|
||||
if (p != ETL_NULLPTR)
|
||||
{
|
||||
::new(p) rcm_t(*this, etl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
ETL_ASSERT((p != ETL_NULLPTR), ETL_ERROR(etl::reference_counted_message_pool_allocation_failure));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate a reference counted message from the pool.
|
||||
//*************************************************************************
|
||||
|
||||
@ -223,6 +223,15 @@ namespace etl
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor.
|
||||
//***************************************************************************
|
||||
template <typename... Args>
|
||||
reference_counted_object(Args&&... args)
|
||||
: object(etl::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Get a reference to the counted object.
|
||||
//***************************************************************************
|
||||
|
||||
@ -49,6 +49,16 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Creator for in-place instantiation
|
||||
//*************************************************************************
|
||||
template <typename TMessage, typename TPool, typename... Args>
|
||||
static shared_message create(TPool& owner, Args&&... args)
|
||||
{
|
||||
const TMessage* msg = nullptr;
|
||||
return shared_message(owner, msg, etl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
@ -59,7 +69,24 @@ namespace etl
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage not derived from etl::imessage");
|
||||
|
||||
p_rcmessage = owner.allocate(message);
|
||||
|
||||
|
||||
if (p_rcmessage != ETL_NULLPTR)
|
||||
{
|
||||
p_rcmessage->get_reference_counter().set_reference_count(1U);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
template <typename TPool, typename TMessage, typename... Args>
|
||||
shared_message(TPool& owner, const TMessage* message, Args&&... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::ireference_counted_message_pool, TPool>::value), "TPool not derived from etl::ireference_counted_message_pool");
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage not derived from etl::imessage");
|
||||
|
||||
p_rcmessage = owner.allocate(message, etl::forward<Args>(args)...);
|
||||
|
||||
if (p_rcmessage != ETL_NULLPTR)
|
||||
{
|
||||
p_rcmessage->get_reference_counter().set_reference_count(1U);
|
||||
|
||||
@ -44,12 +44,33 @@ namespace
|
||||
constexpr etl::message_router_id_t RouterId1 = 1U;
|
||||
constexpr etl::message_router_id_t RouterId2 = 2U;
|
||||
|
||||
int message_1_instantiations = 0;
|
||||
|
||||
//*************************************************************************
|
||||
struct Message1 : public etl::message<MessageId1>
|
||||
{
|
||||
Message1()
|
||||
: i(0)
|
||||
{
|
||||
++message_1_instantiations;
|
||||
}
|
||||
|
||||
Message1(int i_)
|
||||
: i(i_)
|
||||
{
|
||||
++message_1_instantiations;
|
||||
}
|
||||
|
||||
Message1(const Message1& msg)
|
||||
: i(msg.i)
|
||||
{
|
||||
++message_1_instantiations;
|
||||
}
|
||||
|
||||
Message1(Message1&& msg)
|
||||
: i(msg.i)
|
||||
{
|
||||
++message_1_instantiations;
|
||||
}
|
||||
|
||||
~Message1()
|
||||
@ -153,6 +174,27 @@ namespace
|
||||
|
||||
using pool_message_parameters = etl::atomic_counted_message_pool::pool_message_parameters<Message1, Message2>;
|
||||
|
||||
etl::fixed_sized_memory_block_allocator<pool_message_parameters::max_size,
|
||||
pool_message_parameters::max_alignment,
|
||||
4U> memory_allocator;
|
||||
|
||||
class atomic_counted_message_factory : public etl::atomic_counted_message_pool
|
||||
{
|
||||
public:
|
||||
atomic_counted_message_factory(etl::imemory_block_allocator& memory_block_allocator_)
|
||||
: etl::atomic_counted_message_pool(memory_block_allocator_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename TMessage, typename... Args>
|
||||
etl::shared_message create_message(Args&&... args)
|
||||
{
|
||||
return etl::shared_message::create<TMessage>(*this, etl::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
atomic_counted_message_factory message_pool(memory_allocator);
|
||||
|
||||
//*************************************************************************
|
||||
class Message2Allocator : public etl::ireference_counted_message_pool
|
||||
{
|
||||
@ -174,7 +216,7 @@ namespace
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_move_constructor)
|
||||
TEST(test_move_constructor_with_default_constructed_message)
|
||||
{
|
||||
etl::fixed_sized_memory_block_allocator<pool_message_parameters::max_size,
|
||||
pool_message_parameters::max_alignment, 4U> memory_allocator;
|
||||
@ -182,9 +224,46 @@ namespace
|
||||
etl::atomic_counted_message_pool message_pool(memory_allocator);
|
||||
|
||||
#include "etl/private/diagnostic_pessimizing_move_push.h"
|
||||
etl::shared_message sm1(std::move(etl::shared_message(message_pool, Message1(1))));
|
||||
etl::shared_message sm(std::move(etl::shared_message(message_pool, Message1())));
|
||||
#include "etl/private/diagnostic_pop.h"
|
||||
CHECK_EQUAL(1, sm1.get_reference_count());
|
||||
|
||||
CHECK_EQUAL(1, sm.get_reference_count());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_move_constructor_with_default_constructed_message_inplace_in_message_pool)
|
||||
{
|
||||
message_1_instantiations = 0;
|
||||
|
||||
#include "etl/private/diagnostic_pessimizing_move_push.h"
|
||||
etl::shared_message sm (std::move(message_pool.create_message<Message1>()));
|
||||
#include "etl/private/diagnostic_pop.h"
|
||||
|
||||
CHECK_EQUAL(1, sm.get_reference_count());
|
||||
CHECK_EQUAL(1, message_1_instantiations);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_move_constructor_with_parametrized_constructed_message)
|
||||
{
|
||||
#include "etl/private/diagnostic_pessimizing_move_push.h"
|
||||
etl::shared_message sm(std::move(etl::shared_message(message_pool, Message1(1))));
|
||||
#include "etl/private/diagnostic_pop.h"
|
||||
|
||||
CHECK_EQUAL(1, sm.get_reference_count());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_move_constructor_with_parametrized_constructed_message_inplace_in_message_pool)
|
||||
{
|
||||
message_1_instantiations = 0;
|
||||
|
||||
#include "etl/private/diagnostic_pessimizing_move_push.h"
|
||||
etl::shared_message sm (std::move(message_pool.create_message<Message1>(1)));
|
||||
#include "etl/private/diagnostic_pop.h"
|
||||
|
||||
CHECK_EQUAL(1, sm.get_reference_count());
|
||||
CHECK_EQUAL(1, message_1_instantiations);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user