mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-25 02:53:33 +08:00
Allocator interface: getNumBlocks() --> getBlockCapacity()
This commit is contained in:
@@ -26,7 +26,10 @@ public:
|
|||||||
virtual void* allocate(std::size_t size) = 0;
|
virtual void* allocate(std::size_t size) = 0;
|
||||||
virtual void deallocate(const void* ptr) = 0;
|
virtual void deallocate(const void* ptr) = 0;
|
||||||
|
|
||||||
virtual uint16_t getNumBlocks() const = 0;
|
/**
|
||||||
|
* Returns the maximum number of blocks this allocator can allocate.
|
||||||
|
*/
|
||||||
|
virtual uint16_t getBlockCapacity() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +64,7 @@ public:
|
|||||||
virtual void* allocate(std::size_t size);
|
virtual void* allocate(std::size_t size);
|
||||||
virtual void deallocate(const void* ptr);
|
virtual void deallocate(const void* ptr);
|
||||||
|
|
||||||
virtual uint16_t getNumBlocks() const { return NumBlocks; }
|
virtual uint16_t getBlockCapacity() const { return NumBlocks; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of blocks that are currently allocated/unallocated.
|
* Return the number of blocks that are currently allocated/unallocated.
|
||||||
@@ -96,7 +99,7 @@ public:
|
|||||||
virtual void* allocate(std::size_t size);
|
virtual void* allocate(std::size_t size);
|
||||||
virtual void deallocate(const void* ptr);
|
virtual void deallocate(const void* ptr);
|
||||||
|
|
||||||
virtual uint16_t getNumBlocks() const;
|
virtual uint16_t getBlockCapacity() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ class UAVCAN_EXPORT HeapBasedPoolAllocator : public IPoolAllocator, Noncopyable
|
|||||||
};
|
};
|
||||||
|
|
||||||
Node* volatile cache_;
|
Node* volatile cache_;
|
||||||
uint16_t reported_num_blocks_;
|
|
||||||
|
const uint16_t capacity_soft_limit_;
|
||||||
|
const uint16_t capacity_hard_limit_;
|
||||||
|
|
||||||
Node* popCache()
|
Node* popCache()
|
||||||
{
|
{
|
||||||
@@ -58,10 +60,20 @@ class UAVCAN_EXPORT HeapBasedPoolAllocator : public IPoolAllocator, Noncopyable
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The allocator initializes with empty cache, so first allocations will be served from heap.
|
* The allocator initializes with empty cache, so first allocations will be served from heap.
|
||||||
|
*
|
||||||
|
* @param block_capacity_soft_limit Block capacity that will be reported via @ref getBlockCapacity().
|
||||||
|
*
|
||||||
|
* @param block_capacity_hard_limit Real block capacity limit; the number of allocated blocks will never
|
||||||
|
* exceed this value. Hard limit should be higher than soft limit.
|
||||||
|
* Default value is two times the soft limit.
|
||||||
*/
|
*/
|
||||||
HeapBasedPoolAllocator(uint16_t reported_num_blocks) :
|
HeapBasedPoolAllocator(uint16_t block_capacity_soft_limit,
|
||||||
|
uint16_t block_capacity_hard_limit = 0) :
|
||||||
cache_(NULL),
|
cache_(NULL),
|
||||||
reported_num_blocks_(reported_num_blocks)
|
capacity_soft_limit_(block_capacity_soft_limit),
|
||||||
|
capacity_hard_limit_((block_capacity_hard_limit > 0) ? block_capacity_hard_limit :
|
||||||
|
static_cast<uint16_t>(min(static_cast<uint32_t>(block_capacity_soft_limit) * 2U,
|
||||||
|
static_cast<uint32_t>(NumericTraits<uint16_t>::max()))))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,10 +115,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Heap-based pool is virutally infinite in size, so this method just returns some pre-defined value.
|
* The soft limit.
|
||||||
*/
|
*/
|
||||||
virtual uint16_t getNumBlocks() const { return reported_num_blocks_; }
|
virtual uint16_t getBlockCapacity() const { return capacity_soft_limit_; }
|
||||||
void setReportedNumBlocks(uint16_t x) { reported_num_blocks_ = x; }
|
|
||||||
|
/**
|
||||||
|
* The hard limit.
|
||||||
|
*/
|
||||||
|
uint16_t getBlockCapacityHardLimit() const { return capacity_hard_limit_; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees all blocks that are not in use at the moment.
|
* Frees all blocks that are not in use at the moment.
|
||||||
|
|||||||
@@ -295,10 +295,10 @@ CanIOManager::CanIOManager(ICanDriver& driver, IPoolAllocator& allocator, ISyste
|
|||||||
|
|
||||||
if (mem_blocks_per_iface == 0)
|
if (mem_blocks_per_iface == 0)
|
||||||
{
|
{
|
||||||
mem_blocks_per_iface = allocator.getNumBlocks() / (num_ifaces_ + 1U) + 1U;
|
mem_blocks_per_iface = allocator.getBlockCapacity() / (num_ifaces_ + 1U) + 1U;
|
||||||
}
|
}
|
||||||
UAVCAN_TRACE("CanIOManager", "Memory blocks per iface: %u, total: %u",
|
UAVCAN_TRACE("CanIOManager", "Memory blocks per iface: %u, total: %u",
|
||||||
unsigned(mem_blocks_per_iface), unsigned(allocator.getNumBlocks()));
|
unsigned(mem_blocks_per_iface), unsigned(allocator.getBlockCapacity()));
|
||||||
|
|
||||||
for (int i = 0; i < num_ifaces_; i++)
|
for (int i = 0; i < num_ifaces_; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ void LimitedPoolAllocator::deallocate(const void* ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t LimitedPoolAllocator::getNumBlocks() const
|
uint16_t LimitedPoolAllocator::getBlockCapacity() const
|
||||||
{
|
{
|
||||||
return min(max_blocks_, allocator_.getNumBlocks());
|
return min(max_blocks_, allocator_.getBlockCapacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ TEST(DynamicMemory, LimitedPoolAllocator)
|
|||||||
uavcan::PoolAllocator<128, 32> pool32;
|
uavcan::PoolAllocator<128, 32> pool32;
|
||||||
uavcan::LimitedPoolAllocator lim(pool32, 2);
|
uavcan::LimitedPoolAllocator lim(pool32, 2);
|
||||||
|
|
||||||
EXPECT_EQ(2, lim.getNumBlocks());
|
EXPECT_EQ(2, lim.getBlockCapacity());
|
||||||
EXPECT_EQ(0, pool32.getPeakNumUsedBlocks());
|
EXPECT_EQ(0, pool32.getPeakNumUsedBlocks());
|
||||||
|
|
||||||
const void* ptr1 = lim.allocate(1);
|
const void* ptr1 = lim.allocate(1);
|
||||||
|
|||||||
@@ -12,13 +12,12 @@ TEST(HeapBasedPoolAllocator, Basic)
|
|||||||
std::cout << ">>> HEAP BEFORE:" << std::endl;
|
std::cout << ">>> HEAP BEFORE:" << std::endl;
|
||||||
malloc_stats();
|
malloc_stats();
|
||||||
|
|
||||||
uavcan::HeapBasedPoolAllocator<uavcan::MemPoolBlockSize> al(64);
|
uavcan::HeapBasedPoolAllocator<uavcan::MemPoolBlockSize> al(0xEEEE);
|
||||||
|
|
||||||
ASSERT_EQ(0, al.getNumCachedBlocks());
|
ASSERT_EQ(0, al.getNumCachedBlocks());
|
||||||
|
|
||||||
ASSERT_EQ(64, al.getNumBlocks());
|
ASSERT_EQ(0xEEEE, al.getBlockCapacity());
|
||||||
al.setReportedNumBlocks(123);
|
ASSERT_EQ(0xFFFF, al.getBlockCapacityHardLimit());
|
||||||
ASSERT_EQ(123, al.getNumBlocks());
|
|
||||||
|
|
||||||
void* a = al.allocate(10);
|
void* a = al.allocate(10);
|
||||||
void* b = al.allocate(10);
|
void* b = al.allocate(10);
|
||||||
@@ -74,7 +73,10 @@ TEST(HeapBasedPoolAllocator, Concurrency)
|
|||||||
std::cout << ">>> HEAP BEFORE:" << std::endl;
|
std::cout << ">>> HEAP BEFORE:" << std::endl;
|
||||||
malloc_stats();
|
malloc_stats();
|
||||||
|
|
||||||
uavcan::HeapBasedPoolAllocator<uavcan::MemPoolBlockSize, RaiiSynchronizer> al(1);
|
uavcan::HeapBasedPoolAllocator<uavcan::MemPoolBlockSize, RaiiSynchronizer> al(1000);
|
||||||
|
|
||||||
|
ASSERT_EQ(1000, al.getBlockCapacity());
|
||||||
|
ASSERT_EQ(2000, al.getBlockCapacityHardLimit());
|
||||||
|
|
||||||
volatile bool terminate = false;
|
volatile bool terminate = false;
|
||||||
|
|
||||||
|
|||||||
@@ -316,5 +316,5 @@ class NullAllocator : public uavcan::IPoolAllocator
|
|||||||
public:
|
public:
|
||||||
virtual void* allocate(std::size_t) { return NULL; }
|
virtual void* allocate(std::size_t) { return NULL; }
|
||||||
virtual void deallocate(const void*) { }
|
virtual void deallocate(const void*) { }
|
||||||
virtual uint16_t getNumBlocks() const { return 0; }
|
virtual uint16_t getBlockCapacity() const { return 0; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -373,11 +373,11 @@ public:
|
|||||||
{
|
{
|
||||||
assert(num_ifaces_ > 0 && num_ifaces_ <= uavcan::MaxCanIfaces);
|
assert(num_ifaces_ > 0 && num_ifaces_ <= uavcan::MaxCanIfaces);
|
||||||
|
|
||||||
const unsigned quota_per_iface = allocator_.getNumBlocks() / num_ifaces_;
|
const unsigned quota_per_iface = allocator_.getBlockCapacity() / num_ifaces_;
|
||||||
const unsigned quota_per_queue = quota_per_iface; // 2x overcommit
|
const unsigned quota_per_queue = quota_per_iface; // 2x overcommit
|
||||||
|
|
||||||
UAVCAN_TRACE("VirtualCanDriver", "Total blocks: %u, quota per queue: %u",
|
UAVCAN_TRACE("VirtualCanDriver", "Total blocks: %u, quota per queue: %u",
|
||||||
unsigned(allocator_.getNumBlocks()), unsigned(quota_per_queue));
|
unsigned(allocator_.getBlockCapacity()), unsigned(quota_per_queue));
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_ifaces_; i++)
|
for (unsigned i = 0; i < num_ifaces_; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user