Globally defined and statically checked block size for pool allocator

This commit is contained in:
Pavel Kirienko
2014-02-04 20:16:50 +04:00
parent 832f0395bd
commit f91d8090c9
5 changed files with 47 additions and 11 deletions
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <uavcan/internal/static_assert.hpp>
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 <typename T>
struct AssertDynamicallyAllocatable
{
static void check() { StaticAssert<sizeof(T) <= MEM_POOL_BLOCK_SIZE>::check(); }
};
}
@@ -8,7 +8,6 @@
namespace uavcan namespace uavcan
{ {
/** /**
* Usage: * Usage:
* StaticAssert<expression>::check(); * StaticAssert<expression>::check();
@@ -27,4 +26,10 @@ struct StaticAssert<true>
static void check() { } static void check() { }
}; };
/**
* Usage:
* ShowIntegerAsError<integer_expression>::foobar();
*/
template<long N> struct ShowIntegerAsError;
} }
@@ -9,7 +9,7 @@
#include <stdint.h> #include <stdint.h>
#include <uavcan/internal/linked_list.hpp> #include <uavcan/internal/linked_list.hpp>
#include <uavcan/internal/dynamic_memory.hpp> #include <uavcan/internal/dynamic_memory.hpp>
#include <uavcan/internal/static_assert.hpp> #include <uavcan/internal/impl_constants.hpp>
#include <uavcan/can_driver.hpp> #include <uavcan/can_driver.hpp>
#include <uavcan/system_clock.hpp> #include <uavcan/system_clock.hpp>
@@ -33,8 +33,7 @@ class CanTxQueue
public: public:
enum Qos { VOLATILE, PERSISTENT }; enum Qos { VOLATILE, PERSISTENT };
#pragma pack(push, 1) struct Entry : public LinkedListNode<Entry> // Not required to be packed - fits the block in any case
struct Entry : public LinkedListNode<Entry>
{ {
uint64_t monotonic_deadline; uint64_t monotonic_deadline;
CanFrame frame; CanFrame frame;
@@ -46,7 +45,7 @@ public:
, qos(uint8_t(qos)) , qos(uint8_t(qos))
{ {
assert(qos == VOLATILE || qos == PERSISTENT); assert(qos == VOLATILE || qos == PERSISTENT);
StaticAssert<sizeof(Entry) <= 32>::check(); AssertDynamicallyAllocatable<Entry>::check();
} }
bool isExpired(uint64_t monotonic_timestamp) const { return monotonic_timestamp > monotonic_deadline; } bool isExpired(uint64_t monotonic_timestamp) const { return monotonic_timestamp > monotonic_deadline; }
@@ -58,7 +57,6 @@ public:
std::string toString() const; std::string toString() const;
}; };
#pragma pack(pop)
private: private:
class PriorityInsertionComparator class PriorityInsertionComparator
@@ -8,7 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include <uavcan/internal/transport/transfer.hpp> #include <uavcan/internal/transport/transfer.hpp>
#include <uavcan/internal/linked_list.hpp> #include <uavcan/internal/linked_list.hpp>
#include <uavcan/internal/static_assert.hpp> #include <uavcan/internal/impl_constants.hpp>
#include <uavcan/internal/dynamic_memory.hpp> #include <uavcan/internal/dynamic_memory.hpp>
namespace uavcan namespace uavcan
@@ -81,13 +81,13 @@ private:
{ {
enum enum
{ {
NUM_ENTRIES = (32 - sizeof(LinkedListNode<StorageEntryGroup>)) / sizeof(StorageEntry) NUM_ENTRIES = (MEM_POOL_BLOCK_SIZE - sizeof(LinkedListNode<StorageEntryGroup>)) / sizeof(StorageEntry)
}; };
StorageEntry entries[NUM_ENTRIES]; StorageEntry entries[NUM_ENTRIES];
StorageEntryGroup() StorageEntryGroup()
{ {
StaticAssert<sizeof(StorageEntryGroup) <= 32>::check(); AssertDynamicallyAllocatable<StorageEntryGroup>::check();
StaticAssert<NUM_ENTRIES >= 2>::check(); StaticAssert<NUM_ENTRIES >= 2>::check();
} }
}; };
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2014 <pavel.kirienko@gmail.com> * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/ */
#include <gtest/gtest.h> #include <gtest/gtest.h>
@@ -26,7 +26,7 @@ TEST(TransferIDRegistry, Basic)
typedef TransferIDRegistry::Entry Entry; typedef TransferIDRegistry::Entry Entry;
static const int POOL_BLOCKS = 8; static const int POOL_BLOCKS = 8;
uavcan::PoolAllocator<32 * POOL_BLOCKS, 32> pool; uavcan::PoolAllocator<uavcan::MEM_POOL_BLOCK_SIZE * POOL_BLOCKS, uavcan::MEM_POOL_BLOCK_SIZE> pool;
uavcan::PoolManager<2> poolmgr; uavcan::PoolManager<2> poolmgr;
poolmgr.addPool(&pool); poolmgr.addPool(&pool);