Skip to content

Commit

Permalink
Fix formatting
Browse files Browse the repository at this point in the history
Signed-off-by: Emerson Knapp <eknapp@amazon.com>
  • Loading branch information
Emerson Knapp committed May 13, 2019
1 parent ca1eb86 commit 305400e
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 3 deletions.
220 changes: 220 additions & 0 deletions osrf_testing_tools_cpp/src/memory_tools/impl/arena_allocator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#pragma once

#include <cassert>

namespace osrf_testing_tools_cpp
{
namespace memory_tools
{
namespace impl
{

template <std::size_t MemoryPoolSize, std::size_t Align>
class ArenaAllocator;

template <std::size_t PoolSize, std::size_t Alignment = alignof(std::max_align_t)>
class MemoryPool
{
alignas(Alignment) char buf_[PoolSize];
char* ptr_;

public:
~MemoryPool()
{
ptr_ = nullptr;
}

MemoryPool() noexcept
: ptr_(buf_)
{}

MemoryPool(const MemoryPool&) = delete;

MemoryPool& operator=(const MemoryPool&) = delete;

template <std::size_t ReqAlign> char* allocate(std::size_t n);

bool deallocate(char* p, std::size_t n) noexcept;

static constexpr std::size_t size() noexcept
{
return PoolSize;
}

std::size_t used() const noexcept
{
return static_cast<std::size_t>(ptr_ - buf_);
}

void reset() noexcept
{
ptr_ = buf_;
}

private:
static std::size_t
align_up(std::size_t n) noexcept
{
return (n + (Alignment-1)) & ~(Alignment-1);
}

bool
pointer_in_buffer(char* p) noexcept
{
return buf_ <= p && p <= buf_ + PoolSize;
}

friend class ArenaAllocator<PoolSize, Alignment>;
};

template <std::size_t PoolSize, std::size_t Alignment>
template <std::size_t ReqAlign>
char*
MemoryPool<PoolSize, Alignment>::allocate(std::size_t n)
{
static_assert(ReqAlign <= Alignment, "alignment is too small for this arena");
assert(pointer_in_buffer(ptr_) && "Allocator has outlived MemoryPool");
auto const aligned_n = align_up(n);
if (static_cast<decltype(aligned_n)>(buf_ + PoolSize - ptr_) >= aligned_n)
{
char* r = ptr_;
ptr_ += aligned_n;
return r;
}

static_assert(Alignment <= alignof(std::max_align_t), "you've chosen an "
"alignment that is larger than alignof(std::max_align_t), and "
"cannot be guaranteed by normal operator new");
return static_cast<char*>(::operator new(n));
}

template <std::size_t PoolSize, std::size_t Alignment>
bool
MemoryPool<PoolSize, Alignment>::deallocate(char* p, std::size_t n) noexcept
{
assert(pointer_in_buffer(ptr_) && "Allocator has outlived MemoryPool");
if (pointer_in_buffer(p)) {
n = align_up(n);
if (p + n == ptr_) {
ptr_ = p;
}
return true;
}
return false;
}

template <std::size_t MemoryPoolSize, std::size_t Align = alignof(std::max_align_t)>
class ArenaAllocator
{
public:
using value_type = uint8_t;
static auto constexpr alignment = Align;
static auto constexpr size = MemoryPoolSize;
using pool_type = MemoryPool<size, alignment>;

private:
pool_type& pool_;

public:
ArenaAllocator(const ArenaAllocator&) = default;
ArenaAllocator& operator=(const ArenaAllocator&) = delete;

ArenaAllocator(pool_type& p) noexcept : pool_(p)
{
static_assert(size % alignment == 0,
"size MemoryPoolSize needs to be a multiple of alignment Align");
}

void* allocate(std::size_t n)
{
return reinterpret_cast<void*>(pool_.template allocate<alignof(void*)>(n*sizeof(void*)));
}

bool deallocate(void * ptr) noexcept
{
// NOTE never deallocating, we have created a pool large enough for all memory needed
return pool_.pointer_in_buffer(reinterpret_cast<char*>(ptr));
}

void* reallocate(void*, std::size_t n)
{
return this->allocate(n);
}

void* zero_allocate(size_t count, size_t size)
{
size_t total_size = count * size;
void* memory = this->allocate(total_size);
if (nullptr != memory) {
memset(memory, 0x0, total_size);
}
return memory;
}
};


template <std::size_t N>
class ArenaAlloc
{
using value_type = uint8_t;
static auto constexpr alignment = alignof(std::max_align_t);
static auto constexpr size = N;
alignas(alignment) char buf_[N];
char * ptr_;
public:
ArenaAlloc() noexcept : ptr_(buf_) {
static_assert(size % alignment == 0, "size N needs to be a multiple of std::max_align_t");
}
~ArenaAlloc() { ptr_ = nullptr; }

void * allocate(std::size_t n)
{
assert(pointer_in_buffer(ptr_));
auto const aligned_n = align_up(n);
if (static_cast<decltype(aligned_n)>(buf_ + N - ptr_) >= aligned_n) {
char * r = ptr_;
ptr_ += aligned_n;
return r;
}
return nullptr;
}

bool deallocate(void * ptr) noexcept
{
// NOTE never deallocating
return pointer_in_buffer(reinterpret_cast<char *>(ptr));
}

void * reallocate(void *, std::size_t n)
{
// TODO(eknapp) actually reallocate?
return allocate(n);
}

void * zero_allocate(size_t count, size_t size)
{
size_t total_size = count * size;
void * memory = allocate(total_size);
if (nullptr != memory) {
memset(memory, 0x0, total_size);
}
return memory;
}

private:
static std::size_t
align_up(std::size_t n) noexcept
{
return (n + (alignment-1)) & ~(alignment-1);
}

bool pointer_in_buffer(char * p)
{
return buf_ <= p && p <= (buf_ + N);
}
};


}
}
}
6 changes: 3 additions & 3 deletions osrf_testing_tools_cpp/src/memory_tools/impl/linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ find_original_function(const char * name)
// An amount of memory that is greater than what is needed for static initialization
// for any test we run. It was found experimentally on Ubuntu Linux 16.04 x86_64.
static const size_t STATIC_ALLOCATOR_SIZE = 0x800000;
using StaticAllocatorT =
osrf_testing_tools_cpp::memory_tools::impl::StaticAllocator<STATIC_ALLOCATOR_SIZE>;
using osrf_testing_tools_cpp::memory_tools::impl::StaticAllocator;
using StaticAllocatorT = StaticAllocator<STATIC_ALLOCATOR_SIZE>;
static uint8_t g_static_allocator_storage[sizeof(StaticAllocatorT)];

// Contains global allocator to make 100% sure to avoid Static Initialization Order Fiasco.
Expand Down Expand Up @@ -86,7 +86,7 @@ void *
malloc(size_t size) noexcept
{
if (!get_static_initialization_complete()) {
return g_static_allocator()->allocate(size);
return g_static_allocator()->allocate(size);
}
return unix_replacement_malloc(size, g_original_malloc);
}
Expand Down

0 comments on commit 305400e

Please sign in to comment.