diff --git a/libuavcan/include/uavcan/dynamic_memory.hpp b/libuavcan/include/uavcan/dynamic_memory.hpp index d130b8ccb7..28efa1f715 100644 --- a/libuavcan/include/uavcan/dynamic_memory.hpp +++ b/libuavcan/include/uavcan/dynamic_memory.hpp @@ -18,25 +18,23 @@ namespace uavcan /** * This interface is used by other library components that need dynamic memory. */ -class UAVCAN_EXPORT IAllocator +class UAVCAN_EXPORT IPoolAllocator { public: - virtual ~IAllocator() { } + virtual ~IPoolAllocator() { } + virtual void* allocate(std::size_t size) = 0; virtual void deallocate(const void* ptr) = 0; -}; - -class UAVCAN_EXPORT IPoolAllocator : public IAllocator -{ -public: virtual bool isInPool(const void* ptr) const = 0; + virtual std::size_t getBlockSize() const = 0; + virtual std::size_t getNumBlocks() const = 0; }; -template -class UAVCAN_EXPORT PoolManager : public IAllocator, Noncopyable +template +class UAVCAN_EXPORT PoolManager : public IPoolAllocator, Noncopyable { IPoolAllocator* pools_[MaxPools]; @@ -56,8 +54,12 @@ public: bool addPool(IPoolAllocator* pool); void* allocate(std::size_t size); - void deallocate(const void* ptr); + + bool isInPool(const void* ptr) const; + + std::size_t getBlockSize() const; + std::size_t getNumBlocks() const; }; @@ -80,32 +82,31 @@ class UAVCAN_EXPORT PoolAllocator : public IPoolAllocator, Noncopyable } pool_; public: - static const int NumBlocks = int(PoolSize / BlockSize); + static const unsigned NumBlocks = unsigned(PoolSize / BlockSize); PoolAllocator(); void* allocate(std::size_t size); - void deallocate(const void* ptr); bool isInPool(const void* ptr) const; std::size_t getBlockSize() const { return BlockSize; } + std::size_t getNumBlocks() const { return NumBlocks; } - int getNumFreeBlocks() const; - - int getNumUsedBlocks() const { return NumBlocks - getNumFreeBlocks(); } + unsigned getNumFreeBlocks() const; + unsigned getNumUsedBlocks() const { return NumBlocks - getNumFreeBlocks(); } }; -class LimitedPoolAllocator : public IAllocator +class LimitedPoolAllocator : public IPoolAllocator { - IAllocator& allocator_; + IPoolAllocator& allocator_; const std::size_t max_blocks_; std::size_t used_blocks_; public: - LimitedPoolAllocator(IAllocator& allocator, std::size_t max_blocks) + LimitedPoolAllocator(IPoolAllocator& allocator, std::size_t max_blocks) : allocator_(allocator) , max_blocks_(max_blocks) , used_blocks_(0) @@ -115,6 +116,11 @@ public: void* allocate(std::size_t size); void deallocate(const void* ptr); + + bool isInPool(const void* ptr) const; + + std::size_t getBlockSize() const; + std::size_t getNumBlocks() const; }; // ---------------------------------------------------------------------------- @@ -122,12 +128,12 @@ public: /* * PoolManager<> */ -template +template bool PoolManager::addPool(IPoolAllocator* pool) { assert(pool); bool retval = false; - for (int i = 0; i < MaxPools; i++) + for (unsigned i = 0; i < MaxPools; i++) { assert(pools_[i] != pool); if (pools_[i] == NULL || pools_[i] == pool) @@ -142,10 +148,10 @@ bool PoolManager::addPool(IPoolAllocator* pool) return retval; } -template +template void* PoolManager::allocate(std::size_t size) { - for (int i = 0; i < MaxPools; i++) + for (unsigned i = 0; i < MaxPools; i++) { if (pools_[i] == NULL) { @@ -160,10 +166,10 @@ void* PoolManager::allocate(std::size_t size) return NULL; } -template +template void PoolManager::deallocate(const void* ptr) { - for (int i = 0; i < MaxPools; i++) + for (unsigned i = 0; i < MaxPools; i++) { if (pools_[i] == NULL) { @@ -178,6 +184,44 @@ void PoolManager::deallocate(const void* ptr) } } +template +bool PoolManager::isInPool(const void* ptr) const +{ + for (unsigned i = 0; i < MaxPools; i++) + { + if (pools_[i] == NULL) + { + break; + } + if (pools_[i]->isInPool(ptr)) + { + return true; + } + } + return false; +} + +template +std::size_t PoolManager::getBlockSize() const +{ + return 0; +} + +template +std::size_t PoolManager::getNumBlocks() const +{ + std::size_t ret = 0; + for (unsigned i = 0; i < MaxPools; i++) + { + if (pools_[i] == NULL) + { + break; + } + ret += pools_[i]->getNumBlocks(); + } + return ret; +} + /* * PoolAllocator<> */ @@ -186,7 +230,7 @@ PoolAllocator::PoolAllocator() : free_list_(reinterpret_cast(pool_.bytes)) { memset(pool_.bytes, 0, PoolSize); - for (int i = 0; i < NumBlocks - 1; i++) + for (unsigned i = 0; (i + 1) < (NumBlocks - 1 + 1); i++) // -Werror=type-limits { free_list_[i].next = free_list_ + i + 1; } @@ -228,9 +272,9 @@ bool PoolAllocator::isInPool(const void* ptr) const } template -int PoolAllocator::getNumFreeBlocks() const +unsigned PoolAllocator::getNumFreeBlocks() const { - int num = 0; + unsigned num = 0; Node* p = free_list_; while (p) { diff --git a/libuavcan/include/uavcan/map.hpp b/libuavcan/include/uavcan/map.hpp index f65fe2b6a5..ba6b91e025 100644 --- a/libuavcan/include/uavcan/map.hpp +++ b/libuavcan/include/uavcan/map.hpp @@ -50,7 +50,7 @@ class UAVCAN_EXPORT MapBase : Noncopyable IsDynamicallyAllocatable::check(); } - static KVGroup* instantiate(IAllocator& allocator) + static KVGroup* instantiate(IPoolAllocator& allocator) { void* const praw = allocator.allocate(sizeof(KVGroup)); if (praw == NULL) @@ -60,7 +60,7 @@ class UAVCAN_EXPORT MapBase : Noncopyable return new (praw) KVGroup(); } - static void destroy(KVGroup*& obj, IAllocator& allocator) + static void destroy(KVGroup*& obj, IPoolAllocator& allocator) { if (obj != NULL) { @@ -85,7 +85,7 @@ class UAVCAN_EXPORT MapBase : Noncopyable UAVCAN_PACKED_END LinkedListRoot list_; - IAllocator& allocator_; + IPoolAllocator& allocator_; KVPair* const static_; const unsigned num_static_entries_; @@ -101,7 +101,7 @@ class UAVCAN_EXPORT MapBase : Noncopyable }; protected: - MapBase(KVPair* static_buf, unsigned num_static_entries, IAllocator& allocator) + MapBase(KVPair* static_buf, unsigned num_static_entries, IPoolAllocator& allocator) : allocator_(allocator) , static_(static_buf) , num_static_entries_(num_static_entries) @@ -149,7 +149,7 @@ class UAVCAN_EXPORT Map : public MapBase typename MapBase::KVPair static_[NumStaticEntries]; public: - Map(IAllocator& allocator) + Map(IPoolAllocator& allocator) : MapBase(static_, NumStaticEntries, allocator) { } @@ -161,7 +161,7 @@ template class UAVCAN_EXPORT Map : public MapBase { public: - Map(IAllocator& allocator) + Map(IPoolAllocator& allocator) : MapBase(NULL, 0, allocator) { } diff --git a/libuavcan/include/uavcan/node/abstract_node.hpp b/libuavcan/include/uavcan/node/abstract_node.hpp index 20129c62a8..6056cb7ed2 100644 --- a/libuavcan/include/uavcan/node/abstract_node.hpp +++ b/libuavcan/include/uavcan/node/abstract_node.hpp @@ -15,7 +15,7 @@ class UAVCAN_EXPORT INode { public: virtual ~INode() { } - virtual IAllocator& getAllocator() = 0; + virtual IPoolAllocator& getAllocator() = 0; virtual Scheduler& getScheduler() = 0; virtual const Scheduler& getScheduler() const = 0; virtual IMarshalBufferProvider& getMarshalBufferProvider() = 0; diff --git a/libuavcan/include/uavcan/node/generic_subscriber.hpp b/libuavcan/include/uavcan/node/generic_subscriber.hpp index 780e8607ee..dcc7f10120 100644 --- a/libuavcan/include/uavcan/node/generic_subscriber.hpp +++ b/libuavcan/include/uavcan/node/generic_subscriber.hpp @@ -122,7 +122,7 @@ class UAVCAN_EXPORT GenericSubscriber : public GenericSubscriberBase } public: - TransferForwarder(SelfType& obj, const DataTypeDescriptor& data_type, IAllocator& allocator) + TransferForwarder(SelfType& obj, const DataTypeDescriptor& data_type, IPoolAllocator& allocator) : TransferListenerType(obj.node_.getDispatcher().getTransferPerfCounter(), data_type, allocator) , obj_(obj) { } @@ -198,7 +198,7 @@ int GenericSubscriber::checkInit() UAVCAN_TRACE("GenericSubscriber", "Type [%s] is not registered", DataSpec::getDataTypeFullName()); return -ErrUnknownDataType; } - forwarder_.template construct + forwarder_.template construct (*this, *descr, node_.getAllocator()); return 0; } diff --git a/libuavcan/include/uavcan/node/scheduler.hpp b/libuavcan/include/uavcan/node/scheduler.hpp index fd7c05bf0f..88d92332bd 100644 --- a/libuavcan/include/uavcan/node/scheduler.hpp +++ b/libuavcan/include/uavcan/node/scheduler.hpp @@ -77,7 +77,7 @@ class UAVCAN_EXPORT Scheduler : Noncopyable void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin); public: - Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) + Scheduler(ICanDriver& can_driver, IPoolAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) : dispatcher_(can_driver, allocator, sysclock, otr) , prev_cleanup_ts_(sysclock.getMonotonic()) , deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs)) diff --git a/libuavcan/include/uavcan/transport/can_io.hpp b/libuavcan/include/uavcan/transport/can_io.hpp index 63046c4542..815c3735a5 100644 --- a/libuavcan/include/uavcan/transport/can_io.hpp +++ b/libuavcan/include/uavcan/transport/can_io.hpp @@ -59,7 +59,7 @@ public: IsDynamicallyAllocatable::check(); } - static void destroy(Entry*& obj, IAllocator& allocator); + static void destroy(Entry*& obj, IPoolAllocator& allocator); bool isExpired(MonotonicTime timestamp) const { return timestamp > deadline; } @@ -87,7 +87,7 @@ private: }; LinkedListRoot queue_; - IAllocator* const allocator_; + IPoolAllocator* const allocator_; ISystemClock* const sysclock_; uint32_t rejected_frames_cnt_; @@ -100,7 +100,7 @@ public: , rejected_frames_cnt_(0) { } - CanTxQueue(IAllocator* allocator, ISystemClock* sysclock) + CanTxQueue(IPoolAllocator* allocator, ISystemClock* sysclock) : allocator_(allocator) , sysclock_(sysclock) , rejected_frames_cnt_(0) @@ -160,7 +160,7 @@ class UAVCAN_EXPORT CanIOManager : Noncopyable int callSelect(CanSelectMasks& inout_masks, MonotonicTime blocking_deadline); public: - CanIOManager(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock) + CanIOManager(ICanDriver& driver, IPoolAllocator& allocator, ISystemClock& sysclock) : driver_(driver) , sysclock_(sysclock) { diff --git a/libuavcan/include/uavcan/transport/dispatcher.hpp b/libuavcan/include/uavcan/transport/dispatcher.hpp index d30eb72011..50c4d1f3c8 100644 --- a/libuavcan/include/uavcan/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/transport/dispatcher.hpp @@ -102,7 +102,7 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable void handleLoopbackFrame(const CanRxFrame& can_frame); public: - Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) + Dispatcher(ICanDriver& driver, IPoolAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) : canio_(driver, allocator, sysclock) , sysclock_(sysclock) , outgoing_transfer_reg_(otr) diff --git a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp index 9d0f6950c0..2548712108 100644 --- a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp +++ b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp @@ -122,7 +122,7 @@ class UAVCAN_EXPORT OutgoingTransferRegistry : public IOutgoingTransferRegistry, Map map_; public: - OutgoingTransferRegistry(IAllocator& allocator) + OutgoingTransferRegistry(IPoolAllocator& allocator) : map_(allocator) { } diff --git a/libuavcan/include/uavcan/transport/transfer_buffer.hpp b/libuavcan/include/uavcan/transport/transfer_buffer.hpp index 0a8f7f057e..0a1065156f 100644 --- a/libuavcan/include/uavcan/transport/transfer_buffer.hpp +++ b/libuavcan/include/uavcan/transport/transfer_buffer.hpp @@ -107,8 +107,8 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry enum { Size = MemPoolBlockSize - sizeof(LinkedListNode) }; uint8_t data[Size]; - static Block* instantiate(IAllocator& allocator); - static void destroy(Block*& obj, IAllocator& allocator); + static Block* instantiate(IPoolAllocator& allocator); + static void destroy(Block*& obj, IPoolAllocator& allocator); void read(uint8_t*& outptr, unsigned target_offset, unsigned& total_offset, unsigned& left_to_read); @@ -116,7 +116,7 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry unsigned& total_offset, unsigned& left_to_write); }; - IAllocator& allocator_; + IPoolAllocator& allocator_; LinkedListRoot blocks_; // Blocks are ordered from lower to higher buffer offset uint16_t max_write_pos_; const uint16_t max_size_; @@ -124,7 +124,7 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry void resetImpl(); public: - DynamicTransferBufferManagerEntry(IAllocator& allocator, uint16_t max_size) + DynamicTransferBufferManagerEntry(IPoolAllocator& allocator, uint16_t max_size) : allocator_(allocator) , max_write_pos_(0) , max_size_(max_size) @@ -139,8 +139,8 @@ public: resetImpl(); } - static DynamicTransferBufferManagerEntry* instantiate(IAllocator& allocator, uint16_t max_size); - static void destroy(DynamicTransferBufferManagerEntry*& obj, IAllocator& allocator); + static DynamicTransferBufferManagerEntry* instantiate(IPoolAllocator& allocator, uint16_t max_size); + static void destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator); int read(unsigned offset, uint8_t* data, unsigned len) const; int write(unsigned offset, const uint8_t* data, unsigned len); @@ -258,7 +258,7 @@ public: class TransferBufferManagerImpl : public ITransferBufferManager, Noncopyable { LinkedListRoot dynamic_buffers_; - IAllocator& allocator_; + IPoolAllocator& allocator_; const uint16_t max_buf_size_; virtual StaticTransferBufferManagerEntryImpl* getStaticByIndex(uint16_t index) const = 0; @@ -268,7 +268,7 @@ class TransferBufferManagerImpl : public ITransferBufferManager, Noncopyable void optimizeStorage(); public: - TransferBufferManagerImpl(uint16_t max_buf_size, IAllocator& allocator) + TransferBufferManagerImpl(uint16_t max_buf_size, IPoolAllocator& allocator) : allocator_(allocator) , max_buf_size_(max_buf_size) { } @@ -295,7 +295,7 @@ class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl } public: - TransferBufferManager(IAllocator& allocator) + TransferBufferManager(IPoolAllocator& allocator) : TransferBufferManagerImpl(MaxBufSize, allocator) { StaticAssert<(MaxBufSize > 0)>::check(); @@ -307,7 +307,7 @@ class UAVCAN_EXPORT TransferBufferManager<0, 0> : public ITransferBufferManager { public: TransferBufferManager() { } - TransferBufferManager(IAllocator&) { } + TransferBufferManager(IPoolAllocator&) { } ITransferBuffer* access(const TransferBufferManagerKey&) { return NULL; } ITransferBuffer* create(const TransferBufferManagerKey&) { return NULL; } void remove(const TransferBufferManagerKey&) { } diff --git a/libuavcan/include/uavcan/transport/transfer_listener.hpp b/libuavcan/include/uavcan/transport/transfer_listener.hpp index b92fcd9931..a3a885f1c9 100644 --- a/libuavcan/include/uavcan/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/transport/transfer_listener.hpp @@ -145,7 +145,7 @@ class UAVCAN_EXPORT TransferListener : public TransferListenerBase Map receivers_; public: - TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IAllocator& allocator) + TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IPoolAllocator& allocator) : TransferListenerBase(perf, data_type, receivers_, bufmgr_) , bufmgr_(allocator) , receivers_(allocator) @@ -200,7 +200,7 @@ private: public: ServiceResponseTransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, - IAllocator& allocator) + IPoolAllocator& allocator) : BaseType(perf, data_type, allocator) { } diff --git a/libuavcan/src/transport/uc_can_io.cpp b/libuavcan/src/transport/uc_can_io.cpp index 368a8a2ce3..57f7dea8b3 100644 --- a/libuavcan/src/transport/uc_can_io.cpp +++ b/libuavcan/src/transport/uc_can_io.cpp @@ -30,7 +30,7 @@ std::string CanRxFrame::toString(StringRepresentation mode) const /* * CanTxQueue::Entry */ -void CanTxQueue::Entry::destroy(Entry*& obj, IAllocator& allocator) +void CanTxQueue::Entry::destroy(Entry*& obj, IPoolAllocator& allocator) { if (obj != NULL) { diff --git a/libuavcan/src/transport/uc_transfer_buffer.cpp b/libuavcan/src/transport/uc_transfer_buffer.cpp index ce98ae5cd2..4474d58f93 100644 --- a/libuavcan/src/transport/uc_transfer_buffer.cpp +++ b/libuavcan/src/transport/uc_transfer_buffer.cpp @@ -24,7 +24,7 @@ std::string TransferBufferManagerKey::toString() const /* * DynamicTransferBuffer::Block */ -DynamicTransferBufferManagerEntry::Block* DynamicTransferBufferManagerEntry::Block::instantiate(IAllocator& allocator) +DynamicTransferBufferManagerEntry::Block* DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator) { void* const praw = allocator.allocate(sizeof(Block)); if (praw == NULL) @@ -34,7 +34,7 @@ DynamicTransferBufferManagerEntry::Block* DynamicTransferBufferManagerEntry::Blo return new (praw) Block; } -void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IAllocator& allocator) +void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator) { if (obj != NULL) { @@ -75,7 +75,7 @@ void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsi /* * DynamicTransferBuffer */ -DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiate(IAllocator& allocator, +DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiate(IPoolAllocator& allocator, uint16_t max_size) { void* const praw = allocator.allocate(sizeof(DynamicTransferBufferManagerEntry)); @@ -86,7 +86,7 @@ DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiat return new (praw) DynamicTransferBufferManagerEntry(allocator, max_size); } -void DynamicTransferBufferManagerEntry::destroy(DynamicTransferBufferManagerEntry*& obj, IAllocator& allocator) +void DynamicTransferBufferManagerEntry::destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator) { if (obj != NULL) { diff --git a/libuavcan/src/uc_dynamic_memory.cpp b/libuavcan/src/uc_dynamic_memory.cpp index 31dd40e078..4c5ddf5885 100644 --- a/libuavcan/src/uc_dynamic_memory.cpp +++ b/libuavcan/src/uc_dynamic_memory.cpp @@ -33,4 +33,19 @@ void LimitedPoolAllocator::deallocate(const void* ptr) } } +bool LimitedPoolAllocator::isInPool(const void* ptr) const +{ + return allocator_.isInPool(ptr); +} + +std::size_t LimitedPoolAllocator::getBlockSize() const +{ + return allocator_.getBlockSize(); +} + +std::size_t LimitedPoolAllocator::getNumBlocks() const +{ + return allocator_.getNumBlocks(); +} + } diff --git a/libuavcan/test/transport/transfer_test_helpers.hpp b/libuavcan/test/transport/transfer_test_helpers.hpp index 34e67ed759..261fa1f3b8 100644 --- a/libuavcan/test/transport/transfer_test_helpers.hpp +++ b/libuavcan/test/transport/transfer_test_helpers.hpp @@ -120,7 +120,7 @@ class TestListener : public uavcan::TransferListener