From f91d8090c9506a64c2496aa6ed236b6537ea57fa Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Tue, 4 Feb 2014 20:12:27 +0400 Subject: [PATCH] Globally defined and statically checked block size for pool allocator --- .../uavcan/internal/impl_constants.hpp | 33 +++++++++++++++++++ .../include/uavcan/internal/static_assert.hpp | 7 +++- .../uavcan/internal/transport/can_io.hpp | 8 ++--- .../transport/transfer_id_registry.hpp | 6 ++-- .../test/transport/transfer_id_registry.cpp | 4 +-- 5 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 libuavcan/include/uavcan/internal/impl_constants.hpp diff --git a/libuavcan/include/uavcan/internal/impl_constants.hpp b/libuavcan/include/uavcan/internal/impl_constants.hpp new file mode 100644 index 0000000000..d198fe5b90 --- /dev/null +++ b/libuavcan/include/uavcan/internal/impl_constants.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#include + +namespace uavcan +{ + +/** + * Should be OK for any target arch up to AMD64 and any compiler. + * The library leverages compile-time checks to ensure that all types that are subject to dynamic allocation + * fit this size; otherwise compilation fails. + */ +#if UAVCAN_MEM_POOL_BLOCK_SIZE +enum { MEM_POOL_BLOCK_SIZE = UAVCAN_MEM_POOL_BLOCK_SIZE }; +#else +enum { MEM_POOL_BLOCK_SIZE = 48 }; +#endif + +enum { MEM_POOL_ALIGNMENT = 8 }; + +typedef char _alignment_check_for_MEM_POOL_BLOCK_SIZE[((MEM_POOL_BLOCK_SIZE & (MEM_POOL_ALIGNMENT - 1)) == 0) ? 1 : -1]; + +template +struct AssertDynamicallyAllocatable +{ + static void check() { StaticAssert::check(); } +}; + +} diff --git a/libuavcan/include/uavcan/internal/static_assert.hpp b/libuavcan/include/uavcan/internal/static_assert.hpp index 85a707acf2..10964b640d 100644 --- a/libuavcan/include/uavcan/internal/static_assert.hpp +++ b/libuavcan/include/uavcan/internal/static_assert.hpp @@ -8,7 +8,6 @@ namespace uavcan { - /** * Usage: * StaticAssert::check(); @@ -27,4 +26,10 @@ struct StaticAssert static void check() { } }; +/** + * Usage: + * ShowIntegerAsError::foobar(); + */ +template struct ShowIntegerAsError; + } diff --git a/libuavcan/include/uavcan/internal/transport/can_io.hpp b/libuavcan/include/uavcan/internal/transport/can_io.hpp index a0d6916a88..353bced9d4 100644 --- a/libuavcan/include/uavcan/internal/transport/can_io.hpp +++ b/libuavcan/include/uavcan/internal/transport/can_io.hpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -33,8 +33,7 @@ class CanTxQueue public: enum Qos { VOLATILE, PERSISTENT }; -#pragma pack(push, 1) - struct Entry : public LinkedListNode + struct Entry : public LinkedListNode // Not required to be packed - fits the block in any case { uint64_t monotonic_deadline; CanFrame frame; @@ -46,7 +45,7 @@ public: , qos(uint8_t(qos)) { assert(qos == VOLATILE || qos == PERSISTENT); - StaticAssert::check(); + AssertDynamicallyAllocatable::check(); } bool isExpired(uint64_t monotonic_timestamp) const { return monotonic_timestamp > monotonic_deadline; } @@ -58,7 +57,6 @@ public: std::string toString() const; }; -#pragma pack(pop) private: class PriorityInsertionComparator diff --git a/libuavcan/include/uavcan/internal/transport/transfer_id_registry.hpp b/libuavcan/include/uavcan/internal/transport/transfer_id_registry.hpp index 1ae06071ef..d621b12faf 100644 --- a/libuavcan/include/uavcan/internal/transport/transfer_id_registry.hpp +++ b/libuavcan/include/uavcan/internal/transport/transfer_id_registry.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include namespace uavcan @@ -81,13 +81,13 @@ private: { enum { - NUM_ENTRIES = (32 - sizeof(LinkedListNode)) / sizeof(StorageEntry) + NUM_ENTRIES = (MEM_POOL_BLOCK_SIZE - sizeof(LinkedListNode)) / sizeof(StorageEntry) }; StorageEntry entries[NUM_ENTRIES]; StorageEntryGroup() { - StaticAssert::check(); + AssertDynamicallyAllocatable::check(); StaticAssert= 2>::check(); } }; diff --git a/libuavcan/test/transport/transfer_id_registry.cpp b/libuavcan/test/transport/transfer_id_registry.cpp index e83c51b853..75ce7d0a05 100644 --- a/libuavcan/test/transport/transfer_id_registry.cpp +++ b/libuavcan/test/transport/transfer_id_registry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 + * Copyright (C) 2014 Pavel Kirienko */ #include @@ -26,7 +26,7 @@ TEST(TransferIDRegistry, Basic) typedef TransferIDRegistry::Entry Entry; static const int POOL_BLOCKS = 8; - uavcan::PoolAllocator<32 * POOL_BLOCKS, 32> pool; + uavcan::PoolAllocator pool; uavcan::PoolManager<2> poolmgr; poolmgr.addPool(&pool);