From d1511bed5cd486d9c9b2951a014bc7bd1c64d2e6 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 14 Oct 2015 21:36:13 +0300 Subject: [PATCH] Node<> and SubNode<> support custom allocators --- libuavcan/include/uavcan/node/node.hpp | 64 +++++++++++++++------- libuavcan/include/uavcan/node/sub_node.hpp | 32 ++++++++--- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/libuavcan/include/uavcan/node/node.hpp b/libuavcan/include/uavcan/node/node.hpp index 4b573bf42a..d270c8adf9 100644 --- a/libuavcan/include/uavcan/node/node.hpp +++ b/libuavcan/include/uavcan/node/node.hpp @@ -30,21 +30,18 @@ namespace uavcan * This is the top-level node API. * 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. - * Minimum recommended size is 4K * (number of CAN ifaces + 1). - * For simple nodes this number can be reduced. - * For high-traffic nodes the recommended minimum is - * like 16K * (number of CAN ifaces + 1). + * @tparam MemPoolSize Size of memory pool for this node, in bytes. + * Please refer to the documentation for details. + * If this value is zero, the constructor will accept a reference to user-provided allocator. */ -template +template class UAVCAN_EXPORT Node : public INode { - enum - { - MemPoolSize = (MemPoolSize_ < std::size_t(MemPoolBlockSize)) ? std::size_t(MemPoolBlockSize) : MemPoolSize_ - }; - - typedef PoolAllocator Allocator; + typedef typename + Select<(MemPoolSize > 0), + PoolAllocator, // If pool size is specified, use default allocator + IPoolAllocator& // Otherwise use reference to user-provided allocator + >::Result Allocator; Allocator pool_allocator_; Scheduler scheduler_; @@ -60,6 +57,12 @@ class UAVCAN_EXPORT Node : public INode uint64_t internal_failure_cnt_; bool started_; + void commonInit() + { + internal_failure_cnt_ = 0; + started_ = false; + } + protected: virtual void registerInternalFailure(const char* msg) { @@ -73,20 +76,43 @@ protected: } public: - Node(ICanDriver& can_driver, ISystemClock& system_clock) - : scheduler_(can_driver, pool_allocator_, system_clock) - , proto_nsp_(*this) + /** + * This overload is only valid if MemPoolSize > 0. + */ + Node(ICanDriver& can_driver, + ISystemClock& system_clock) : + 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 - , 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::Type& getAllocator() { return pool_allocator_; } virtual Scheduler& getScheduler() { return scheduler_; } virtual const Scheduler& getScheduler() const { return scheduler_; } diff --git a/libuavcan/include/uavcan/node/sub_node.hpp b/libuavcan/include/uavcan/node/sub_node.hpp index ef5881cb12..438d1d6815 100644 --- a/libuavcan/include/uavcan/node/sub_node.hpp +++ b/libuavcan/include/uavcan/node/sub_node.hpp @@ -20,15 +20,14 @@ namespace uavcan * 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. */ -template +template class UAVCAN_EXPORT SubNode : public INode { - enum - { - MemPoolSize = (MemPoolSize_ < std::size_t(MemPoolBlockSize)) ? std::size_t(MemPoolBlockSize) : MemPoolSize_ - }; - - typedef PoolAllocator Allocator; + typedef typename + Select<(MemPoolSize > 0), + PoolAllocator, // If pool size is specified, use default allocator + IPoolAllocator& // Otherwise use reference to user-provided allocator + >::Result Allocator; Allocator pool_allocator_; Scheduler scheduler_; @@ -44,12 +43,27 @@ protected: } 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), 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::Type& getAllocator() { return pool_allocator_; } virtual Scheduler& getScheduler() { return scheduler_; } virtual const Scheduler& getScheduler() const { return scheduler_; }