#854 in-place construction of shared message

This commit is contained in:
John Wellbelove 2024-03-09 10:11:00 +00:00
parent 71644ef90c
commit 0cf4396fcb
5 changed files with 51 additions and 49 deletions

View File

@ -74,9 +74,9 @@ namespace etl
/// \param owner The message owner.
/// \param args The constructor arguments.
//***************************************************************************
template <typename... Args>
reference_counted_message(etl::ireference_counted_message_pool& owner_, Args&&... args)
: rc_object(etl::forward<Args>(args)...)
template <typename... TArgs>
reference_counted_message(etl::ireference_counted_message_pool& owner_, TArgs&&... args)
: rc_object(etl::forward<TArgs>(args)...)
, owner(owner_)
{
}
@ -225,4 +225,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -103,8 +103,8 @@ 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)
template <typename TMessage, typename... TArgs>
etl::reference_counted_message<TMessage, TCounter>* allocate(TArgs&&... args)
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
@ -119,7 +119,7 @@ namespace etl
if (p != ETL_NULLPTR)
{
::new(p) rcm_t(*this, etl::forward<Args>(args)...);
::new(p) rcm_t(*this, etl::forward<TArgs>(args)...);
}
ETL_ASSERT((p != ETL_NULLPTR), ETL_ERROR(etl::reference_counted_message_pool_allocation_failure));
@ -209,13 +209,13 @@ namespace etl
// Size of the first pool message type.
static constexpr size_t size1 = sizeof(etl::reference_counted_message<TMessage1, TCounter>);
// Maximum size of the the rest of the pool message types.
// Maximum size of the rest of the pool message types.
static constexpr size_t size2 = pool_message_parameters<TMessages...>::max_size;
// Size of the first pool message type.
static constexpr size_t alignment1 = etl::alignment_of<etl::reference_counted_message<TMessage1, TCounter>>::value;
// Maximum size of the the rest of the pool message types.
// Maximum size of the rest of the pool message types.
static constexpr size_t alignment2 = pool_message_parameters<TMessages...>::max_alignment;
public:
@ -243,8 +243,8 @@ namespace etl
};
#else
template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct pool_message_parameters
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage1 not derived from etl::imessage");
@ -257,23 +257,23 @@ namespace etl
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage8 not derived from etl::imessage");
static ETL_CONSTANT size_t max_size = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
static ETL_CONSTANT size_t max_alignment = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
};
#endif
@ -317,4 +317,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -226,9 +226,9 @@ namespace etl
//***************************************************************************
/// Constructor.
//***************************************************************************
template <typename... Args>
reference_counted_object(Args&&... args)
: object(etl::forward<Args>(args)...)
template <typename... TArgs>
reference_counted_object(TArgs&&... args)
: object(etl::forward<TArgs>(args)...)
{
}
@ -285,4 +285,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -52,11 +52,10 @@ namespace etl
//*************************************************************************
/// Creator for in-place instantiation
//*************************************************************************
template <typename TMessage, typename TPool, typename... Args>
static shared_message create(TPool& owner, Args&&... args)
template <typename TMessage, typename TPool, typename... TArgs>
static shared_message create(TPool& owner, TArgs&&... args)
{
const TMessage* msg = nullptr;
return shared_message(owner, msg, etl::forward<Args>(args)...);
return shared_message(owner, etl::type_tag<TMessage>(), etl::forward<TArgs>(args)...);
}
//*************************************************************************
@ -79,13 +78,13 @@ namespace etl
//*************************************************************************
/// Constructor
//*************************************************************************
template <typename TPool, typename TMessage, typename... Args>
shared_message(TPool& owner, const TMessage* message, Args&&... args)
template <typename TPool, typename TMessage, typename... TArgs>
shared_message(TPool& owner, etl::type_tag<TMessage>, TArgs&&... 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)...);
p_rcmessage = owner.template allocate<TMessage>(etl::forward<TArgs>(args)...);
if (p_rcmessage != ETL_NULLPTR)
{
@ -220,5 +219,4 @@ namespace etl
};
}
#endif
#endif

View File

@ -50,25 +50,29 @@ namespace
struct Message1 : public etl::message<MessageId1>
{
Message1()
: i(0)
: message()
, i(0)
{
++message_1_instantiations;
}
Message1(int i_)
: i(i_)
: message()
, i(i_)
{
++message_1_instantiations;
}
Message1(const Message1& msg)
: i(msg.i)
: message()
, i(msg.i)
{
++message_1_instantiations;
}
Message1(Message1&& msg)
: i(msg.i)
: message()
, i(msg.i)
{
++message_1_instantiations;
}
@ -176,7 +180,7 @@ namespace
etl::fixed_sized_memory_block_allocator<pool_message_parameters::max_size,
pool_message_parameters::max_alignment,
4U> memory_allocator;
4U> common_memory_allocator;
class atomic_counted_message_factory : public etl::atomic_counted_message_pool
{
@ -193,7 +197,7 @@ namespace
}
};
atomic_counted_message_factory message_pool(memory_allocator);
atomic_counted_message_factory common_message_pool(common_memory_allocator);
//*************************************************************************
class Message2Allocator : public etl::ireference_counted_message_pool
@ -236,7 +240,7 @@ namespace
message_1_instantiations = 0;
#include "etl/private/diagnostic_pessimizing_move_push.h"
etl::shared_message sm (std::move(message_pool.create_message<Message1>()));
etl::shared_message sm (std::move(common_message_pool.create_message<Message1>()));
#include "etl/private/diagnostic_pop.h"
CHECK_EQUAL(1, sm.get_reference_count());
@ -247,7 +251,7 @@ namespace
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))));
etl::shared_message sm(std::move(etl::shared_message(common_message_pool, Message1(1))));
#include "etl/private/diagnostic_pop.h"
CHECK_EQUAL(1, sm.get_reference_count());
@ -259,7 +263,7 @@ namespace
message_1_instantiations = 0;
#include "etl/private/diagnostic_pessimizing_move_push.h"
etl::shared_message sm (std::move(message_pool.create_message<Message1>(1)));
etl::shared_message sm (std::move(common_message_pool.create_message<Message1>(1)));
#include "etl/private/diagnostic_pop.h"
CHECK_EQUAL(1, sm.get_reference_count());
@ -380,4 +384,4 @@ namespace
CHECK_THROW(message_pool.release(temp), etl::reference_counted_message_pool_release_failure);
}
}
}
}