diff --git a/CMakeLists.txt b/CMakeLists.txt index f83e2ab8..f1367e91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,8 @@ list ( alloc/aligned/foreign.hpp alloc/allocator.cpp alloc/allocator.hpp + alloc/chunked.cpp + alloc/chunked.hpp alloc/easy.hpp alloc/fallback.cpp alloc/fallback.hpp diff --git a/alloc/chunked.cpp b/alloc/chunked.cpp new file mode 100644 index 00000000..22d14a95 --- /dev/null +++ b/alloc/chunked.cpp @@ -0,0 +1,14 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2021, Danny Robson + */ + +#include "chunked.hpp" + +using cruft::alloc::chunked; + + +/////////////////////////////////////////////////////////////////////////////// diff --git a/alloc/chunked.hpp b/alloc/chunked.hpp new file mode 100644 index 00000000..c90342ea --- /dev/null +++ b/alloc/chunked.hpp @@ -0,0 +1,89 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2021, Danny Robson + */ + +#pragma once + +#if 0 && __has_include() + #include +#else + #include +#endif + +#include + + +namespace std::pmr { + class memory_resource { + public: + memory_resource () = default; + memory_resource (memory_resource const&) = default; + memory_resource& operator= (memory_resource const&) = default; + virtual ~memory_resource () = default; + + [[nodiscard]] void* allocate ( + std::size_t bytes, + std::size_t alignment = alignof (std::max_align_t) + ); + + void deallocate( + void* p, + std::size_t bytes, + std::size_t alignment = alignof(std::max_align_t) + ); + + bool is_equal (memory_resource const&) const noexcept; + + private: + virtual void *do_allocate (std::size_t bytes, std::size_t alignment) = 0; + virtual void do_deallocate (void *p, std::size_t bytes, std::size_t alignment) = 0; + virtual bool do_is_equal (memory_resource const&) const noexcept = 0; + }; +} + + +/////////////////////////////////////////////////////////////////////////////// +namespace cruft::alloc { + /// An unbounded contiguous allocator that operates on chunks, similar to + /// a deque. + /// + /// It's useful as a means to keep unknown sized allocations in roughly + /// the same memory region. + /// + /// This class models std::pmr::memory_resource. + class chunked : public std::pmr::memory_resource { + public: + static constexpr std::size_t DEFAULT_CHUNK_SIZE = 4096; + + explicit chunked (std::size_t initial_size); + chunked (std::size_t initial_size, std::size_t chunk_size); + + private: + void* do_allocate ( + std::size_t bytes, + std::size_t alignment = alignof (std::max_align_t) + ) override; + + void do_deallocate ( + void *p, + std::size_t bytes, + std::size_t alignment = alignof (std::max_align_t) + ) override; + + bool do_is_equal (memory_resource const&) const noexcept override; + + std::size_t m_chunk; + struct arena { + std::byte* base; + std::size_t size; + std::byte* next; + }; + + std::vector m_data; + int m_next; + }; +} \ No newline at end of file