From a5c69c5911d68dbece637830dfa52dc4d4250d03 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 12 Jan 2021 14:58:55 +1000 Subject: [PATCH] alloc/chunked: add untested initial implementation --- alloc/chunked.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++ alloc/chunked.hpp | 22 +++++++++----- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/alloc/chunked.cpp b/alloc/chunked.cpp index 22d14a95..ee6a1edb 100644 --- a/alloc/chunked.cpp +++ b/alloc/chunked.cpp @@ -8,7 +8,82 @@ #include "chunked.hpp" +#include "../log.hpp" +#include "../maths.hpp" +#include "../pointer.hpp" + + using cruft::alloc::chunked; /////////////////////////////////////////////////////////////////////////////// +chunked::chunked (std::size_t initial_size) + : chunked (initial_size, DEFAULT_CHUNK_SIZE) +{ ; } + + +//----------------------------------------------------------------------------- +chunked::chunked (std::size_t initial_size, std::size_t _chunk_size) + : m_chunk (_chunk_size) +{ + m_chunk = cruft::max (m_chunk, sizeof (node_t)); + + auto const initial_arenas = cruft::divup (initial_size, m_chunk); + m_data.resize (initial_arenas); + + for (auto &i: m_data) { + i.data = new std::byte[m_chunk]; + *i.node = { + .size = m_chunk, + .next = nullptr + }; + } +} + + +/////////////////////////////////////////////////////////////////////////////// +void* +chunked::do_allocate (std::size_t size, std::size_t alignment) +{ + // Find a chunk that can service this allocation. + for (auto &i: m_data) { + if (i.node->size < size + alignment) + continue; + + auto base = cruft::align::up (i.data, alignment); + std::byte* newbase = base + size; + if (newbase > i.data + i.node->size) + continue; + + std::size_t newsize = i.data + i.node->size - newbase; + + i.data = newbase; + i.node->size = newsize; + + return base; + } + + // No chunk was found. We need to allocate a new chunk of at least enough size. + unimplemented (); +} + + +//----------------------------------------------------------------------------- +void +chunked::do_deallocate (void *p, std::size_t bytes, std::size_t alignment) +{ + (void)p; + (void)bytes; + (void)alignment; + + LOG_WARNING ("chunked::do_deallocate is unimplemented"); +} + + +//----------------------------------------------------------------------------- +bool +chunked::do_is_equal (memory_resource const &) const noexcept +{ + warn ("chunked::do_is_equal is unimplemented"); + return false; +} \ No newline at end of file diff --git a/alloc/chunked.hpp b/alloc/chunked.hpp index c90342ea..299ebcaf 100644 --- a/alloc/chunked.hpp +++ b/alloc/chunked.hpp @@ -14,6 +14,7 @@ #include #endif +#include #include @@ -28,15 +29,18 @@ namespace std::pmr { [[nodiscard]] void* allocate ( std::size_t bytes, std::size_t alignment = alignof (std::max_align_t) - ); + ) { return do_allocate (bytes, alignment); } void deallocate( void* p, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t) - ); + ) { return do_deallocate (p, bytes, alignment); } - bool is_equal (memory_resource const&) const noexcept; + bool is_equal (memory_resource const &rhs) const noexcept + { + return do_is_equal (rhs); + } private: virtual void *do_allocate (std::size_t bytes, std::size_t alignment) = 0; @@ -77,13 +81,17 @@ namespace cruft::alloc { bool do_is_equal (memory_resource const&) const noexcept override; std::size_t m_chunk; - struct arena { - std::byte* base; + + struct node_t { std::size_t size; - std::byte* next; + node_t* next; + }; + + union arena { + std::byte *data; + node_t *node; }; std::vector m_data; - int m_next; }; } \ No newline at end of file