Node<> and SubNode<> support custom allocators

This commit is contained in:
Pavel Kirienko
2015-10-14 21:36:13 +03:00
parent 23352746cd
commit d1511bed5c
2 changed files with 68 additions and 28 deletions
+45 -19
View File
@@ -30,21 +30,18 @@ namespace uavcan
* This is the top-level node API. * This is the top-level node API.
* A custom node class can be implemented if needed, in which case it shall inherit INode. * A custom node class can be implemented if needed, in which case it shall inherit INode.
* *
* @tparam MemPoolSize_ Size of memory pool for this node, in bytes. * @tparam MemPoolSize Size of memory pool for this node, in bytes.
* Minimum recommended size is 4K * (number of CAN ifaces + 1). * Please refer to the documentation for details.
* For simple nodes this number can be reduced. * If this value is zero, the constructor will accept a reference to user-provided allocator.
* For high-traffic nodes the recommended minimum is
* like 16K * (number of CAN ifaces + 1).
*/ */
template <std::size_t MemPoolSize_> template <std::size_t MemPoolSize>
class UAVCAN_EXPORT Node : public INode class UAVCAN_EXPORT Node : public INode
{ {
enum typedef typename
{ Select<(MemPoolSize > 0),
MemPoolSize = (MemPoolSize_ < std::size_t(MemPoolBlockSize)) ? std::size_t(MemPoolBlockSize) : MemPoolSize_ PoolAllocator<MemPoolSize, MemPoolBlockSize>, // If pool size is specified, use default allocator
}; IPoolAllocator& // Otherwise use reference to user-provided allocator
>::Result Allocator;
typedef PoolAllocator<MemPoolSize, MemPoolBlockSize> Allocator;
Allocator pool_allocator_; Allocator pool_allocator_;
Scheduler scheduler_; Scheduler scheduler_;
@@ -60,6 +57,12 @@ class UAVCAN_EXPORT Node : public INode
uint64_t internal_failure_cnt_; uint64_t internal_failure_cnt_;
bool started_; bool started_;
void commonInit()
{
internal_failure_cnt_ = 0;
started_ = false;
}
protected: protected:
virtual void registerInternalFailure(const char* msg) virtual void registerInternalFailure(const char* msg)
{ {
@@ -73,20 +76,43 @@ protected:
} }
public: public:
Node(ICanDriver& can_driver, ISystemClock& system_clock) /**
: scheduler_(can_driver, pool_allocator_, system_clock) * This overload is only valid if MemPoolSize > 0.
, proto_nsp_(*this) */
Node(ICanDriver& can_driver,
ISystemClock& system_clock) :
scheduler_(can_driver, pool_allocator_, system_clock),
proto_nsp_(*this)
#if !UAVCAN_TINY #if !UAVCAN_TINY
, proto_dtp_(*this) , proto_dtp_(*this)
, proto_logger_(*this) , proto_logger_(*this)
, proto_rrs_(*this) , proto_rrs_(*this)
, proto_tsp_(*this) , proto_tsp_(*this)
#endif #endif
, internal_failure_cnt_(0) {
, started_(false) commonInit();
{ } }
virtual Allocator& getAllocator() { return pool_allocator_; } /**
* This overload is only valid if MemPoolSize == 0.
*/
Node(ICanDriver& can_driver,
ISystemClock& system_clock,
IPoolAllocator& allocator) :
pool_allocator_(allocator),
scheduler_(can_driver, pool_allocator_, system_clock),
proto_nsp_(*this)
#if !UAVCAN_TINY
, proto_dtp_(*this)
, proto_logger_(*this)
, proto_rrs_(*this)
, proto_tsp_(*this)
#endif
{
commonInit();
}
virtual typename RemoveReference<Allocator>::Type& getAllocator() { return pool_allocator_; }
virtual Scheduler& getScheduler() { return scheduler_; } virtual Scheduler& getScheduler() { return scheduler_; }
virtual const Scheduler& getScheduler() const { return scheduler_; } virtual const Scheduler& getScheduler() const { return scheduler_; }
+23 -9
View File
@@ -20,15 +20,14 @@ namespace uavcan
* Please refer to the @ref Node<> for documentation concerning the template arguments; refer to the tutorials * Please refer to the @ref Node<> for documentation concerning the template arguments; refer to the tutorials
* to lean how to use libuavcan in multiprocess applications. * to lean how to use libuavcan in multiprocess applications.
*/ */
template <std::size_t MemPoolSize_> template <std::size_t MemPoolSize>
class UAVCAN_EXPORT SubNode : public INode class UAVCAN_EXPORT SubNode : public INode
{ {
enum typedef typename
{ Select<(MemPoolSize > 0),
MemPoolSize = (MemPoolSize_ < std::size_t(MemPoolBlockSize)) ? std::size_t(MemPoolBlockSize) : MemPoolSize_ PoolAllocator<MemPoolSize, MemPoolBlockSize>, // If pool size is specified, use default allocator
}; IPoolAllocator& // Otherwise use reference to user-provided allocator
>::Result Allocator;
typedef PoolAllocator<MemPoolSize, MemPoolBlockSize> Allocator;
Allocator pool_allocator_; Allocator pool_allocator_;
Scheduler scheduler_; Scheduler scheduler_;
@@ -44,12 +43,27 @@ protected:
} }
public: public:
SubNode(ICanDriver& can_driver, ISystemClock& system_clock) : /**
* This overload is only valid if MemPoolSize > 0.
*/
SubNode(ICanDriver& can_driver,
ISystemClock& system_clock) :
scheduler_(can_driver, pool_allocator_, system_clock), scheduler_(can_driver, pool_allocator_, system_clock),
internal_failure_cnt_(0) internal_failure_cnt_(0)
{ } { }
virtual Allocator& getAllocator() { return pool_allocator_; } /**
* This overload is only valid if MemPoolSize == 0.
*/
SubNode(ICanDriver& can_driver,
ISystemClock& system_clock,
IPoolAllocator& allocator) :
pool_allocator_(allocator),
scheduler_(can_driver, pool_allocator_, system_clock),
internal_failure_cnt_(0)
{ }
virtual typename RemoveReference<Allocator>::Type& getAllocator() { return pool_allocator_; }
virtual Scheduler& getScheduler() { return scheduler_; } virtual Scheduler& getScheduler() { return scheduler_; }
virtual const Scheduler& getScheduler() const { return scheduler_; } virtual const Scheduler& getScheduler() const { return scheduler_; }