Proper data alignment for allocator and lazy constructor

This commit is contained in:
Pavel Kirienko
2014-03-28 13:47:21 +04:00
parent c54b3314e4
commit 4886e2194f
2 changed files with 29 additions and 17 deletions
+11 -5
View File
@@ -117,7 +117,13 @@ class PoolAllocator : public IPoolAllocator, Noncopyable
}; };
Node* free_list_; Node* free_list_;
uint8_t pool_[PoolSize] __attribute__((aligned(16))); // TODO: compiler-independent alignment union
{
uint8_t bytes[PoolSize];
long double _aligner1;
long long _aligner2;
Node _aligner3;
} pool_;
// Noncopyable // Noncopyable
PoolAllocator(const PoolAllocator&); PoolAllocator(const PoolAllocator&);
@@ -127,9 +133,9 @@ public:
static const int NumBlocks = int(PoolSize / BlockSize); static const int NumBlocks = int(PoolSize / BlockSize);
PoolAllocator() PoolAllocator()
: free_list_(reinterpret_cast<Node*>(pool_)) // TODO: alignment : free_list_(reinterpret_cast<Node*>(pool_.bytes))
{ {
memset(pool_, 0, PoolSize); memset(pool_.bytes, 0, PoolSize);
for (int i = 0; i < NumBlocks - 1; i++) for (int i = 0; i < NumBlocks - 1; i++)
{ {
free_list_[i].next = free_list_ + i + 1; free_list_[i].next = free_list_ + i + 1;
@@ -165,8 +171,8 @@ public:
bool isInPool(const void* ptr) const bool isInPool(const void* ptr) const
{ {
return return
ptr >= pool_ && ptr >= pool_.bytes &&
ptr < (pool_ + PoolSize); ptr < (pool_.bytes + PoolSize);
} }
std::size_t getBlockSize() const { return BlockSize; } std::size_t getBlockSize() const { return BlockSize; }
@@ -18,7 +18,13 @@ namespace uavcan
template <typename T> template <typename T>
class LazyConstructor class LazyConstructor
{ {
unsigned char data_[sizeof(T)] __attribute__((aligned(16))); // TODO: compiler-independent alignment union
{
unsigned char pool[sizeof(T)];
long double _aligner1;
long long _aligner2;
} data_;
T* ptr_; T* ptr_;
void ensureConstructed() const void ensureConstructed() const
@@ -47,13 +53,13 @@ public:
LazyConstructor() LazyConstructor()
: ptr_(NULL) : ptr_(NULL)
{ {
std::fill(data_, data_ + sizeof(T), 0); std::fill(data_.pool, data_.pool + sizeof(T), 0);
} }
LazyConstructor(const LazyConstructor<T>& rhs) LazyConstructor(const LazyConstructor<T>& rhs)
: ptr_(NULL) : ptr_(NULL)
{ {
std::fill(data_, data_ + sizeof(T), 0); std::fill(data_.pool, data_.pool + sizeof(T), 0);
if (rhs) if (rhs)
{ {
construct<const T&>(*rhs); // Invoke copy constructor construct<const T&>(*rhs); // Invoke copy constructor
@@ -89,13 +95,13 @@ public:
ptr_->~T(); ptr_->~T();
} }
ptr_ = NULL; ptr_ = NULL;
std::fill(data_, data_ + sizeof(T), 0); std::fill(data_.pool, data_.pool + sizeof(T), 0);
} }
void construct() void construct()
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(); ptr_ = new (static_cast<void*>(data_.pool)) T();
} }
// MAX_ARGS = 6 // MAX_ARGS = 6
@@ -104,7 +110,7 @@ public:
// void construct(%s) // void construct(%s)
// { // {
// ensureNotConstructed(); // ensureNotConstructed();
// ptr_ = new (static_cast<void*>(data_)) T(%s); // ptr_ = new (static_cast<void*>(data_.pool)) T(%s);
// }''' // }'''
// for nargs in range(1, MAX_ARGS + 1): // for nargs in range(1, MAX_ARGS + 1):
// nums = [(x + 1) for x in range(nargs)] // nums = [(x + 1) for x in range(nargs)]
@@ -117,21 +123,21 @@ public:
void construct(typename ParamType<P1>::Type p1) void construct(typename ParamType<P1>::Type p1)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1); ptr_ = new (static_cast<void*>(data_.pool)) T(p1);
} }
template <typename P1, typename P2> template <typename P1, typename P2>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2) void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2); ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2);
} }
template <typename P1, typename P2, typename P3> template <typename P1, typename P2, typename P3>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3) void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3); ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3);
} }
template <typename P1, typename P2, typename P3, typename P4> template <typename P1, typename P2, typename P3, typename P4>
@@ -139,7 +145,7 @@ public:
typename ParamType<P4>::Type p4) typename ParamType<P4>::Type p4)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4); ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4);
} }
template <typename P1, typename P2, typename P3, typename P4, typename P5> template <typename P1, typename P2, typename P3, typename P4, typename P5>
@@ -147,7 +153,7 @@ public:
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5) typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5); ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4, p5);
} }
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
@@ -155,7 +161,7 @@ public:
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5, typename ParamType<P6>::Type p6) typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5, typename ParamType<P6>::Type p6)
{ {
ensureNotConstructed(); ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5, p6); ptr_ = new (static_cast<void*>(data_.pool)) T(p1, p2, p3, p4, p5, p6);
} }
}; };