From 660e84e17f8dbcfec03d4c3bd5b8c67321a7f552 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 16 Oct 2015 14:31:42 +0300 Subject: [PATCH] Allocator interface: getNumBlocks() --> getBlockCapacity() --- libuavcan/include/uavcan/dynamic_memory.hpp | 9 ++++-- .../helpers/heap_based_pool_allocator.hpp | 28 +++++++++++++++---- libuavcan/src/transport/uc_can_io.cpp | 4 +-- libuavcan/src/uc_dynamic_memory.cpp | 4 +-- libuavcan/test/dynamic_memory.cpp | 2 +- .../helpers/heap_based_pool_allocator.cpp | 12 ++++---- .../test/transport/transfer_test_helpers.hpp | 2 +- .../linux/apps/test_multithreading.cpp | 4 +-- 8 files changed, 43 insertions(+), 22 deletions(-) diff --git a/libuavcan/include/uavcan/dynamic_memory.hpp b/libuavcan/include/uavcan/dynamic_memory.hpp index 5d440724d6..425d7ca6b4 100644 --- a/libuavcan/include/uavcan/dynamic_memory.hpp +++ b/libuavcan/include/uavcan/dynamic_memory.hpp @@ -26,7 +26,10 @@ public: virtual void* allocate(std::size_t size) = 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 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. @@ -96,7 +99,7 @@ public: virtual void* allocate(std::size_t size); virtual void deallocate(const void* ptr); - virtual uint16_t getNumBlocks() const; + virtual uint16_t getBlockCapacity() const; }; // ---------------------------------------------------------------------------- diff --git a/libuavcan/include/uavcan/helpers/heap_based_pool_allocator.hpp b/libuavcan/include/uavcan/helpers/heap_based_pool_allocator.hpp index ad217a241a..0034ec9b31 100644 --- a/libuavcan/include/uavcan/helpers/heap_based_pool_allocator.hpp +++ b/libuavcan/include/uavcan/helpers/heap_based_pool_allocator.hpp @@ -33,7 +33,9 @@ class UAVCAN_EXPORT HeapBasedPoolAllocator : public IPoolAllocator, Noncopyable }; Node* volatile cache_; - uint16_t reported_num_blocks_; + + const uint16_t capacity_soft_limit_; + const uint16_t capacity_hard_limit_; Node* popCache() { @@ -58,10 +60,20 @@ class UAVCAN_EXPORT HeapBasedPoolAllocator : public IPoolAllocator, Noncopyable public: /** * 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), - 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(min(static_cast(block_capacity_soft_limit) * 2U, + static_cast(NumericTraits::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_; } - void setReportedNumBlocks(uint16_t x) { reported_num_blocks_ = x; } + virtual uint16_t getBlockCapacity() const { return capacity_soft_limit_; } + + /** + * The hard limit. + */ + uint16_t getBlockCapacityHardLimit() const { return capacity_hard_limit_; } /** * Frees all blocks that are not in use at the moment. diff --git a/libuavcan/src/transport/uc_can_io.cpp b/libuavcan/src/transport/uc_can_io.cpp index 2fb36ec69c..d6417a670c 100644 --- a/libuavcan/src/transport/uc_can_io.cpp +++ b/libuavcan/src/transport/uc_can_io.cpp @@ -295,10 +295,10 @@ CanIOManager::CanIOManager(ICanDriver& driver, IPoolAllocator& allocator, ISyste 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", - unsigned(mem_blocks_per_iface), unsigned(allocator.getNumBlocks())); + unsigned(mem_blocks_per_iface), unsigned(allocator.getBlockCapacity())); for (int i = 0; i < num_ifaces_; i++) { diff --git a/libuavcan/src/uc_dynamic_memory.cpp b/libuavcan/src/uc_dynamic_memory.cpp index 68925f1d11..1b682f6b1b 100644 --- a/libuavcan/src/uc_dynamic_memory.cpp +++ b/libuavcan/src/uc_dynamic_memory.cpp @@ -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()); } } diff --git a/libuavcan/test/dynamic_memory.cpp b/libuavcan/test/dynamic_memory.cpp index 21ba7e4487..cbe3650614 100644 --- a/libuavcan/test/dynamic_memory.cpp +++ b/libuavcan/test/dynamic_memory.cpp @@ -49,7 +49,7 @@ TEST(DynamicMemory, LimitedPoolAllocator) uavcan::PoolAllocator<128, 32> pool32; uavcan::LimitedPoolAllocator lim(pool32, 2); - EXPECT_EQ(2, lim.getNumBlocks()); + EXPECT_EQ(2, lim.getBlockCapacity()); EXPECT_EQ(0, pool32.getPeakNumUsedBlocks()); const void* ptr1 = lim.allocate(1); diff --git a/libuavcan/test/helpers/heap_based_pool_allocator.cpp b/libuavcan/test/helpers/heap_based_pool_allocator.cpp index 2f029241d3..96783acfd8 100644 --- a/libuavcan/test/helpers/heap_based_pool_allocator.cpp +++ b/libuavcan/test/helpers/heap_based_pool_allocator.cpp @@ -12,13 +12,12 @@ TEST(HeapBasedPoolAllocator, Basic) std::cout << ">>> HEAP BEFORE:" << std::endl; malloc_stats(); - uavcan::HeapBasedPoolAllocator al(64); + uavcan::HeapBasedPoolAllocator al(0xEEEE); ASSERT_EQ(0, al.getNumCachedBlocks()); - ASSERT_EQ(64, al.getNumBlocks()); - al.setReportedNumBlocks(123); - ASSERT_EQ(123, al.getNumBlocks()); + ASSERT_EQ(0xEEEE, al.getBlockCapacity()); + ASSERT_EQ(0xFFFF, al.getBlockCapacityHardLimit()); void* a = al.allocate(10); void* b = al.allocate(10); @@ -74,7 +73,10 @@ TEST(HeapBasedPoolAllocator, Concurrency) std::cout << ">>> HEAP BEFORE:" << std::endl; malloc_stats(); - uavcan::HeapBasedPoolAllocator al(1); + uavcan::HeapBasedPoolAllocator al(1000); + + ASSERT_EQ(1000, al.getBlockCapacity()); + ASSERT_EQ(2000, al.getBlockCapacityHardLimit()); volatile bool terminate = false; diff --git a/libuavcan/test/transport/transfer_test_helpers.hpp b/libuavcan/test/transport/transfer_test_helpers.hpp index aa52154ea4..55dda5a35f 100644 --- a/libuavcan/test/transport/transfer_test_helpers.hpp +++ b/libuavcan/test/transport/transfer_test_helpers.hpp @@ -316,5 +316,5 @@ class NullAllocator : public uavcan::IPoolAllocator public: virtual void* allocate(std::size_t) { return NULL; } virtual void deallocate(const void*) { } - virtual uint16_t getNumBlocks() const { return 0; } + virtual uint16_t getBlockCapacity() const { return 0; } }; diff --git a/libuavcan_drivers/linux/apps/test_multithreading.cpp b/libuavcan_drivers/linux/apps/test_multithreading.cpp index f46d5a46cf..fb143e3cf2 100644 --- a/libuavcan_drivers/linux/apps/test_multithreading.cpp +++ b/libuavcan_drivers/linux/apps/test_multithreading.cpp @@ -373,11 +373,11 @@ public: { 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 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++) {