diff --git a/src/caliper/MemoryPool.cpp b/src/caliper/MemoryPool.cpp index 84ee53014..623d33f75 100644 --- a/src/caliper/MemoryPool.cpp +++ b/src/caliper/MemoryPool.cpp @@ -57,24 +57,26 @@ struct MemoryPool::MemoryPoolImpl m_total_reserved += len; } - void* allocate(size_t bytes, bool can_expand) { - size_t n = bytes + ((bytes+7)%8); - + void* allocate(size_t bytes, size_t alignment, bool can_expand) { std::lock_guard g(m_lock); - if (m_chunks.empty() || m_chunks.back().wmark + n > m_chunks.back().size) { + if (m_chunks.empty() || m_chunks.back().wmark + bytes + alignment > m_chunks.back().size) { if (can_expand) expand(bytes); else return nullptr; } - void *ptr = static_cast(m_chunks.back().ptr + m_chunks.back().wmark); - m_chunks.back().wmark += n; + unsigned char *ptr = m_chunks.back().ptr + m_chunks.back().wmark; + std::uintptr_t pn = reinterpret_cast(ptr); + std::uintptr_t aligned = (pn + alignment-1) & - alignment; + std::size_t n = bytes + (aligned - pn); + m_chunks.back().wmark += n; m_total_used += n; - return ptr; + + return reinterpret_cast(aligned); } void merge(MemoryPoolImpl& other) { @@ -157,7 +159,12 @@ MemoryPool::~MemoryPool() void* MemoryPool::allocate(size_t bytes) { - return mP->allocate(bytes, mP->m_can_expand); + return mP->allocate(bytes, 1, mP->m_can_expand); +} + +void* MemoryPool::allocate(size_t bytes, size_t alignment) +{ + return mP->allocate(bytes, alignment, mP->m_can_expand); } void MemoryPool::merge(MemoryPool& other) diff --git a/src/caliper/MemoryPool.h b/src/caliper/MemoryPool.h index aba25682f..75533fe56 100644 --- a/src/caliper/MemoryPool.h +++ b/src/caliper/MemoryPool.h @@ -38,13 +38,18 @@ class MemoryPool // --- allocate void* allocate(std::size_t bytes); + void* allocate(std::size_t bytes, std::size_t alignment); template T* aligned_alloc(std::size_t n = 1, std::size_t a = alignof(T)) { +/* + // ancient gcc 4.9-based STL versions don't have std::align :-(( std::size_t size = n * sizeof(T); std::size_t space = n * sizeof(T) + a; void* p = allocate(space); return reinterpret_cast(std::align(a, size, p, space)); +*/ + return reinterpret_cast(allocate(n*sizeof(T), a)); } /// \brief Move \a other's data into this mempool.