Out of line methods in dynamic_memory.hpp

This commit is contained in:
Pavel Kirienko 2014-04-08 18:54:05 +04:00
parent a13e4de58a
commit a32d0d335c

View File

@ -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<Node*>(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<Node*>(const_cast<void*>(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 <int MaxPools>
bool PoolManager<MaxPools>::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 <int MaxPools>
void* PoolManager<MaxPools>::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 <int MaxPools>
void PoolManager<MaxPools>::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 <std::size_t PoolSize, std::size_t BlockSize>
PoolAllocator<PoolSize, BlockSize>::PoolAllocator()
: free_list_(reinterpret_cast<Node*>(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 <std::size_t PoolSize, std::size_t BlockSize>
void* PoolAllocator<PoolSize, BlockSize>::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 <std::size_t PoolSize, std::size_t BlockSize>
void PoolAllocator<PoolSize, BlockSize>::deallocate(const void* ptr)
{
if (ptr == NULL)
{
return;
}
Node* p = static_cast<Node*>(const_cast<void*>(ptr));
#if DEBUG || UAVCAN_DEBUG
std::memset(p, 0, sizeof(Node));
#endif
p->next = free_list_;
free_list_ = p;
}
template <std::size_t PoolSize, std::size_t BlockSize>
bool PoolAllocator<PoolSize, BlockSize>::isInPool(const void* ptr) const
{
return ptr >= pool_.bytes &&
ptr < (pool_.bytes + PoolSize);
}
template <std::size_t PoolSize, std::size_t BlockSize>
int PoolAllocator<PoolSize, BlockSize>::getNumFreeBlocks() const
{
int num = 0;
Node* p = free_list_;
while (p)
{
num++;
assert(num <= NumBlocks);
p = p->next;
}
return num;
}
}