mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-26 00:43:34 +08:00
Out of line methods in dynamic_memory.hpp
This commit is contained in:
@@ -52,58 +52,11 @@ public:
|
|||||||
std::memset(pools_, 0, sizeof(pools_));
|
std::memset(pools_, 0, sizeof(pools_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addPool(IPoolAllocator* pool)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* allocate(std::size_t size)
|
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 deallocate(const void* ptr)
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -128,68 +81,143 @@ class UAVCAN_EXPORT PoolAllocator : public IPoolAllocator, Noncopyable
|
|||||||
public:
|
public:
|
||||||
static const int NumBlocks = int(PoolSize / BlockSize);
|
static const int NumBlocks = int(PoolSize / BlockSize);
|
||||||
|
|
||||||
PoolAllocator()
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* allocate(std::size_t size)
|
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 deallocate(const void* ptr)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInPool(const void* ptr) const
|
bool isInPool(const void* ptr) const;
|
||||||
{
|
|
||||||
return
|
|
||||||
ptr >= pool_.bytes &&
|
|
||||||
ptr < (pool_.bytes + PoolSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t getBlockSize() const { return BlockSize; }
|
std::size_t getBlockSize() const { return BlockSize; }
|
||||||
|
|
||||||
int getNumFreeBlocks() const
|
int getNumFreeBlocks() const;
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
Node* p = free_list_;
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
num++;
|
|
||||||
assert(num <= NumBlocks);
|
|
||||||
p = p->next;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getNumUsedBlocks() const
|
int getNumUsedBlocks() const { return NumBlocks - getNumFreeBlocks(); }
|
||||||
{
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user