From a32d0d335cb463b865b60e828d72bc643dea8acc Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 8 Apr 2014 18:54:05 +0400 Subject: [PATCH] Out of line methods in dynamic_memory.hpp --- libuavcan/include/uavcan/dynamic_memory.hpp | 238 +++++++++++--------- 1 file changed, 133 insertions(+), 105 deletions(-) diff --git a/libuavcan/include/uavcan/dynamic_memory.hpp b/libuavcan/include/uavcan/dynamic_memory.hpp index 41cb62d7cb..cd5f158ff9 100644 --- a/libuavcan/include/uavcan/dynamic_memory.hpp +++ b/libuavcan/include/uavcan/dynamic_memory.hpp @@ -52,58 +52,11 @@ public: std::memset(pools_, 0, sizeof(pools_)); } - bool addPool(IPoolAllocator* pool) - { - assert(pool); - bool retval = false; - for (int i = 0; i < MaxPools; i++) - { - assert(pools_[i] != pool); - if (pools_[i] == NULL || pools_[i] == pool) - { - pools_[i] = pool; - retval = true; - break; - } - } - // We need to keep the pools in order, so that smallest blocks go first - std::sort(pools_, pools_ + MaxPools, &PoolManager::sortComparePoolAllocators); - return retval; - } + bool addPool(IPoolAllocator* pool); - void* allocate(std::size_t size) - { - for (int i = 0; i < MaxPools; i++) - { - if (pools_[i] == NULL) - { - break; - } - void* const pmem = pools_[i]->allocate(size); - if (pmem != NULL) - { - return pmem; - } - } - return NULL; - } + void* allocate(std::size_t size); - void deallocate(const void* ptr) - { - for (int i = 0; i < MaxPools; i++) - { - if (pools_[i] == NULL) - { - assert(0); - break; - } - if (pools_[i]->isInPool(ptr)) - { - pools_[i]->deallocate(ptr); - break; - } - } - } + void deallocate(const void* ptr); }; @@ -128,68 +81,143 @@ class UAVCAN_EXPORT PoolAllocator : public IPoolAllocator, Noncopyable public: static const int NumBlocks = int(PoolSize / BlockSize); - PoolAllocator() - : free_list_(reinterpret_cast(pool_.bytes)) - { - memset(pool_.bytes, 0, PoolSize); - for (int i = 0; i < NumBlocks - 1; i++) - { - free_list_[i].next = free_list_ + i + 1; - } - free_list_[NumBlocks - 1].next = NULL; - } + PoolAllocator(); - void* allocate(std::size_t size) - { - if (free_list_ == NULL || size > BlockSize) - { - return NULL; - } - void* pmem = free_list_; - free_list_ = free_list_->next; - return pmem; - } + void* allocate(std::size_t size); - void deallocate(const void* ptr) - { - if (ptr == NULL) - { - return; - } - Node* p = static_cast(const_cast(ptr)); -#if DEBUG || UAVCAN_DEBUG - std::memset(p, 0, sizeof(Node)); -#endif - p->next = free_list_; - free_list_ = p; - } + void deallocate(const void* ptr); - bool isInPool(const void* ptr) const - { - return - ptr >= pool_.bytes && - ptr < (pool_.bytes + PoolSize); - } + bool isInPool(const void* ptr) const; std::size_t getBlockSize() const { return BlockSize; } - int getNumFreeBlocks() const - { - int num = 0; - Node* p = free_list_; - while (p) - { - num++; - assert(num <= NumBlocks); - p = p->next; - } - return num; - } + int getNumFreeBlocks() const; - int getNumUsedBlocks() const - { - return NumBlocks - getNumFreeBlocks(); - } + int getNumUsedBlocks() const { return NumBlocks - getNumFreeBlocks(); } }; +// ---------------------------------------------------------------------------- + +/* + * PoolManager<> + */ +template +bool PoolManager::addPool(IPoolAllocator* pool) +{ + assert(pool); + bool retval = false; + for (int i = 0; i < MaxPools; i++) + { + assert(pools_[i] != pool); + if (pools_[i] == NULL || pools_[i] == pool) + { + pools_[i] = pool; + retval = true; + break; + } + } + // We need to keep the pools in order, so that smallest blocks go first + std::sort(pools_, pools_ + MaxPools, &PoolManager::sortComparePoolAllocators); + return retval; +} + +template +void* PoolManager::allocate(std::size_t size) +{ + for (int i = 0; i < MaxPools; i++) + { + if (pools_[i] == NULL) + { + break; + } + void* const pmem = pools_[i]->allocate(size); + if (pmem != NULL) + { + return pmem; + } + } + return NULL; +} + +template +void PoolManager::deallocate(const void* ptr) +{ + for (int i = 0; i < MaxPools; i++) + { + if (pools_[i] == NULL) + { + assert(0); + break; + } + if (pools_[i]->isInPool(ptr)) + { + pools_[i]->deallocate(ptr); + break; + } + } +} + +/* + * PoolAllocator<> + */ +template +PoolAllocator::PoolAllocator() + : free_list_(reinterpret_cast(pool_.bytes)) +{ + memset(pool_.bytes, 0, PoolSize); + for (int i = 0; i < NumBlocks - 1; i++) + { + free_list_[i].next = free_list_ + i + 1; + } + free_list_[NumBlocks - 1].next = NULL; +} + +template +void* PoolAllocator::allocate(std::size_t size) +{ + if (free_list_ == NULL || size > BlockSize) + { + return NULL; + } + void* pmem = free_list_; + free_list_ = free_list_->next; + return pmem; +} + +template +void PoolAllocator::deallocate(const void* ptr) +{ + if (ptr == NULL) + { + return; + } + Node* p = static_cast(const_cast(ptr)); +#if DEBUG || UAVCAN_DEBUG + std::memset(p, 0, sizeof(Node)); +#endif + p->next = free_list_; + free_list_ = p; +} + +template +bool PoolAllocator::isInPool(const void* ptr) const +{ + return ptr >= pool_.bytes && + ptr < (pool_.bytes + PoolSize); +} + +template +int PoolAllocator::getNumFreeBlocks() const +{ + int num = 0; + Node* p = free_list_; + while (p) + { + num++; + assert(num <= NumBlocks); + p = p->next; + } + return num; +} + }