reference_counted_object and reference_counted_message specialisations

This commit is contained in:
John Wellbelove 2021-01-02 19:42:27 +00:00
parent ecee02d41d
commit dc25df16db
4 changed files with 75 additions and 137 deletions

View File

@ -104,46 +104,23 @@ namespace etl
etl::reference_counted_object<TMessage, TCounter> rc_object;
};
#if ETL_HAS_ATOMIC
//***************************************************************************
/// Class for creating reference counted messages using an atomic counter.
/// \tparam TMessage The type to be reference counted.
/// Persistent message type.
/// The message type will always have a reference count of 1.
/// \tparam TMessage The message type stored.
//***************************************************************************
template <typename TMessage>
class atomic_counted_message : virtual public etl::reference_counted_message<TMessage, etl::atomic_int32_t>
{
public:
//***************************************************************************
/// Constructor.
/// \param msg The message to count.
//***************************************************************************
atomic_counted_message(const TMessage& msg_)
: reference_counted_message<TMessage, etl::atomic_int32_t>(msg_)
{
}
typedef typename reference_counted_message<TMessage, etl::atomic_int32_t>::message_type message_type;
typedef typename reference_counted_message<TMessage, etl::atomic_int32_t>::counter_type counter_type;
};
#endif
//***************************************************************************
// Uncounted message type.
//***************************************************************************
template <typename TMessage>
class reference_counted_message<TMessage, void> : virtual public etl::ireference_counted_message
class persistent_message : virtual public etl::ireference_counted_message
{
public:
typedef TMessage message_type;
typedef void counter_type;
//***************************************************************************
/// Constructor
/// \param msg The message to count.
//***************************************************************************
reference_counted_message(const TMessage& msg_)
persistent_message(const TMessage& msg_)
: rc_object(msg_)
{
}
@ -177,30 +154,23 @@ namespace etl
private:
// This class must not be default contructed, copy constructed or assigned.
persistent_message() ETL_DELETE;
persistent_message(const persistent_message&) ETL_DELETE;
persistent_message& operator =(const persistent_message&) ETL_DELETE;
/// The reference counted object.
etl::reference_counted_object<TMessage, void> rc_object;
etl::persistent_object<TMessage> rc_object;
};
#if ETL_CPP11_SUPPORTED && ETL_HAS_ATOMIC
//***************************************************************************
/// Synonym for reference_counted_message<TMessage, void>
/// \tparam TObject The type stored in the object.
/// Class for creating reference counted objects using an atomic counter.
/// \tparam TObject The type to be reference counted.
//***************************************************************************
template <typename TMessage>
class uncounted_message : public etl::reference_counted_message<TMessage, void>
{
public:
//***************************************************************************
/// Constructor.
//***************************************************************************
uncounted_message(const TMessage& msg_)
: reference_counted_message<TMessage, void>(msg_)
{
}
typedef typename reference_counted_message<TMessage, void>::message_type message_type;
typedef typename reference_counted_message<TMessage, void>::counter_type counter_type;
};
using atomic_counted_message = etl::reference_counted_message<TMessage, etl::atomic_int32_t>;
#endif
}
#endif

View File

@ -72,7 +72,7 @@ namespace etl
//};
//***************************************************************************
///
/// Iterface for a reference counted message pool.
//***************************************************************************
class ireference_counted_message_pool
{
@ -83,7 +83,7 @@ namespace etl
};
//***************************************************************************
///
/// A pool for allocating reference counted messages.
//***************************************************************************
template <typename TCounter>
class reference_counted_message_pool : public ireference_counted_message_pool
@ -98,13 +98,17 @@ namespace etl
//{
//}
reference_counted_message_pool()
{
}
//*************************************************************************
/// Allocate a reference counted message from the pool.
//*************************************************************************
template <typename TMessage>
etl::ireference_counted_message* allocate(const TMessage& message)
{
//ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
using ref_message_t = etl::reference_counted_message<TMessage, TCounter>;
@ -135,7 +139,7 @@ namespace etl
template <typename TMessage, typename... TArgs>
etl::ireference_counted_message* allocate(TArgs&&... args)
{
//ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
using ref_message_t = etl::reference_counted_message<TMessage, TCounter>;
@ -298,15 +302,13 @@ namespace etl
//*************************************************************************
/// Destruct a message and send it back to the pool.
//*************************************************************************
void release(const etl::ireference_counted_message* const prcm)
void release(const etl::ireference_counted_message* const p_rcmessage)
{
std::cout << "reference_counted_message_pool : release\n";
if (prcm != ETL_NULLPTR)
if (p_rcmessage != ETL_NULLPTR)
{
// prcm->~ireference_counted_message();
delete prcm;
//memory_block_pool.release_memory_block(prcm);
// p_rcmessage->~ireference_counted_message();
delete p_rcmessage;
//memory_block_pool.release_memory_block(p_rcmessage);
}
}
@ -323,9 +325,9 @@ namespace etl
/// 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;
// Should not be copied.
reference_counted_message_pool(const reference_counted_message_pool&) ETL_DELETE;
reference_counted_message_pool& operator =(const reference_counted_message_pool&) ETL_DELETE;
};
}

View File

@ -44,10 +44,10 @@ namespace etl
public:
virtual ~ireference_counted_object() {};
virtual void set_reference_count(uint32_t value) = 0;
virtual void set_reference_count(int32_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;
ETL_NODISCARD virtual int32_t decrement_reference_count() = 0;
ETL_NODISCARD virtual int32_t get_reference_count() const = 0;
};
//***************************************************************************
@ -83,7 +83,7 @@ namespace etl
//***************************************************************************
/// Set the reference count.
//***************************************************************************
virtual void set_reference_count(uint32_t value) ETL_OVERRIDE
virtual void set_reference_count(int32_t value) ETL_OVERRIDE
{
reference_count = value;
}
@ -99,19 +99,19 @@ namespace etl
//***************************************************************************
/// Decrement the refernce count.
//***************************************************************************
ETL_NODISCARD virtual uint32_t decrement_reference_count() ETL_OVERRIDE
ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE
{
assert(reference_count > 0);
return uint32_t(--reference_count);
return int32_t(--reference_count);
}
//***************************************************************************
/// Get the current reference count.
//***************************************************************************
ETL_NODISCARD virtual uint32_t get_reference_count() const ETL_OVERRIDE
ETL_NODISCARD virtual int32_t get_reference_count() const ETL_OVERRIDE
{
return uint32_t(reference_count);
return int32_t(reference_count);
}
private:
@ -125,46 +125,22 @@ namespace etl
const TObject object; // The object being reference counted.
};
#if ETL_HAS_ATOMIC
//***************************************************************************
/// Class for creating reference counted objects using an atomic counter.
/// \tparam TObject The type to be reference counted.
//***************************************************************************
template <typename TObject>
class atomic_counted_object : public etl::reference_counted_object<TObject, etl::atomic_int32_t>
{
public:
//***************************************************************************
/// Constructor.
//***************************************************************************
atomic_counted_object(const TObject& object_)
: reference_counted_object<TObject, etl::atomic_int32_t>(object_)
{
}
typedef typename reference_counted_object<TObject, etl::atomic_int32_t>::value_type value_type;
typedef typename reference_counted_object<TObject, etl::atomic_int32_t>::counter_type counter_type;
};
#endif
//***************************************************************************
/// Specialisation creating objects that have the ireference_counted_object interface
/// but do not actually count.
/// Persistent message type.
/// The message type will always have a reference count of 1.
/// \tparam TObject The type stored in the object.
//***************************************************************************
template <typename TObject>
class reference_counted_object<TObject, void> : public etl::ireference_counted_object
class persistent_object : public etl::ireference_counted_object
{
public:
typedef TObject value_type;
typedef void counter_type;
typedef TObject value_type;
//***************************************************************************
/// Constructor.
//***************************************************************************
reference_counted_object(const TObject& object_)
persistent_object(const TObject& object_)
: object(object_)
{
}
@ -188,7 +164,7 @@ namespace etl
//***************************************************************************
/// Set the reference count.
//***************************************************************************
virtual void set_reference_count(uint32_t value) ETL_OVERRIDE
virtual void set_reference_count(int32_t) ETL_OVERRIDE
{
}
@ -202,7 +178,7 @@ namespace etl
//***************************************************************************
/// Decrement the refernce count.
//***************************************************************************
ETL_NODISCARD virtual uint32_t decrement_reference_count() ETL_OVERRIDE
ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE
{
return 1;
}
@ -210,36 +186,29 @@ namespace etl
//***************************************************************************
/// Get the current reference count.
//***************************************************************************
ETL_NODISCARD virtual uint32_t get_reference_count() const ETL_OVERRIDE
ETL_NODISCARD virtual int32_t get_reference_count() const ETL_OVERRIDE
{
return 1;
}
private:
// This class must not be default contructed, copy constructed or assigned.
persistent_object() ETL_DELETE;
persistent_object(const persistent_object&) ETL_DELETE;
persistent_object& operator =(const persistent_object&) ETL_DELETE;
TObject object; // The object being reference counted.
};
#if ETL_CPP11_SUPPORTED && ETL_HAS_ATOMIC
//***************************************************************************
/// Synonym for reference_counted_object<TObject, void>
/// \tparam TObject The type stored in the object.
/// Class for creating reference counted objects using an atomic counter.
/// \tparam TObject The type to be reference counted.
//***************************************************************************
template <typename TObject>
class uncounted_object : public etl::reference_counted_object<TObject, void>
{
public:
//***************************************************************************
/// Constructor.
//***************************************************************************
uncounted_object(const TObject& object_)
: reference_counted_object<TObject>(object_)
{
}
typedef typename reference_counted_object<TObject, void>::value_type value_type;
typedef typename reference_counted_object<TObject, void>::counter_type counter_type;
};
using atomic_counted_object = etl::reference_counted_object<TObject, etl::atomic_int32_t>;
#endif
}
#endif

View File

@ -31,8 +31,6 @@ SOFTWARE.
#ifndef ETL_SHARED_MESSAGE_INCLUDED
#define ETL_SHARED_MESSAGE_INCLUDED
#include <iostream>
#include "platform.h"
#include "reference_counted_message_pool.h"
#include "reference_counted_message.h"
@ -57,15 +55,18 @@ namespace etl
, p_rcmessage(&message_)
{
p_rcmessage->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
//*************************************************************************
/// Constructor
/// \param pmessage A reference to the message allocated from the pool.
//*************************************************************************
shared_message(etl::ireference_counted_message& message_)
: p_rcmessage_owner(ETL_NULLPTR)
, p_rcmessage(&message_)
{
p_rcmessage->get_reference_counter().set_reference_count(1U);
std::cout << "shared_message C : ID = " << int(p_rcmessage->get_message().get_message_id()) << " No Owner\n";
}
//*************************************************************************
@ -76,7 +77,6 @@ namespace etl
, p_rcmessage(other.p_rcmessage)
{
p_rcmessage->get_reference_counter().increment_reference_count();
std::cout << "shared_message CC : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
//*************************************************************************
@ -89,7 +89,6 @@ namespace etl
// Deal with the current message.
if (p_rcmessage->get_reference_counter().decrement_reference_count() == 0U)
{
std::cout << "shared_message =: Destroy reference counted message\n";
if (p_rcmessage_owner != ETL_NULLPTR)
{
p_rcmessage_owner->release(p_rcmessage);
@ -100,7 +99,6 @@ namespace etl
p_rcmessage_owner = other.p_rcmessage_owner;
p_rcmessage = other.p_rcmessage;
p_rcmessage->get_reference_counter().increment_reference_count();
std::cout << "shared_message =: ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
return *this;
@ -116,17 +114,8 @@ namespace etl
{
if (is_owned())
{
std::cout << "shared_message ~: Destroy reference counted message\n";
p_rcmessage_owner->release(p_rcmessage);
}
else
{
std::cout << "shared_message ~: Uncounted message\n";
}
}
else
{
std::cout << "shared_message ~ : ID = " << int(p_rcmessage->get_message().get_message_id()) << " : Count = " << p_rcmessage->get_reference_counter().get_reference_count() << "\n";
}
}
@ -162,19 +151,27 @@ namespace etl
etl::ireference_counted_message* p_rcmessage;
};
//*****************************************************************************
/// A wrapper for reference counted messages.
/// Contains pointers to a pool owner and a message defined with a ref count type.
//*****************************************************************************
template <typename TPool, typename TMessage>
etl::shared_message make_shared_message(TPool& owner, const TMessage& message)
{
etl::ireference_counted_message* prcm = owner.allocate(message);
return etl::shared_message(*prcm, owner);
etl::ireference_counted_message* p_rcmessage = owner.allocate(message);
return etl::shared_message(*p_rcmessage, owner);
}
#if ETL_CPP11_SUPPORTED
//*****************************************************************************
/// A wrapper for reference counted messages.
/// Contains pointers to a pool owner and a message defined with a ref count type.
//*****************************************************************************
template <typename TMessage, typename TPool, typename... TArgs>
etl::shared_message make_shared_message(TPool& owner, TArgs&&... args)
{
etl::ireference_counted_message* prcm = owner.allocate<TMessage>(etl::forward<TArgs>(args)...);
return etl::shared_message(*prcm, owner);
etl::ireference_counted_message* p_rcmessage = owner.allocate<TMessage>(etl::forward<TArgs>(args)...);
return etl::shared_message(*p_rcmessage, owner);
}
#endif
}