mijin2/source/mijin/memory/data_pool.hpp
2023-05-29 14:51:44 +02:00

91 lines
2.1 KiB
C++

#pragma once
#if !defined(MIJIN_MEMORY_DATA_POOL_HPP_INCLUDED)
#define MIJIN_MEMORY_DATA_POOL_HPP_INCLUDED 1
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
namespace mijin
{
//
// public defines
//
//
// public constants
//
//
// public types
//
template<std::size_t PAGE_SIZE = 4096ul * 1024ul>
struct DataPool
{
static_assert(PAGE_SIZE % alignof(std::max_align_t) == 0);
struct alignas(std::max_align_t) Page : std::array<std::uint8_t, PAGE_SIZE> {};
using page_ptr_t = std::unique_ptr<Page>;
std::vector<page_ptr_t> pages;
std::size_t offset = 0;
DataPool() = default;
DataPool(const DataPool&) = delete;
DataPool(DataPool&&) noexcept = default;
DataPool& operator=(const DataPool&) = delete;
DataPool& operator=(DataPool&&) noexcept = default;
void* allocate(std::size_t bytes, std::size_t alignment = 1);
inline void reset() { offset = 0; }
template<typename T>
T* allocateAs(std::size_t elements = 1) {
return static_cast<T*>(allocate(sizeof(T) * elements, alignof(T)));
}
};
//
// public functions
//
template<std::size_t PAGE_SIZE>
void* DataPool<PAGE_SIZE>::allocate(std::size_t bytes, std::size_t alignment)
{
assert(bytes > 0 && bytes <= PAGE_SIZE);
assert(alignment > 0 && alignment <= alignof(std::max_align_t));
if (offset % alignment != 0) {
offset += alignment - (offset % alignment);
}
const std::size_t remainingOnPage = PAGE_SIZE - (offset % PAGE_SIZE);
const std::size_t page = offset / PAGE_SIZE;
const std::size_t localOffset = offset % PAGE_SIZE;
if (remainingOnPage == PAGE_SIZE || remainingOnPage < bytes)
{
// next page
if (page + 1 >= pages.size()) {
pages.push_back(std::make_unique<Page>());
}
offset = PAGE_SIZE * (pages.size() - 1);
}
std::uint8_t* result = &(*pages[page])[localOffset];
offset += bytes;
assert(reinterpret_cast<std::uintptr_t>(result) % alignment == 0);
return result;
}
} // namespace mijin
#endif // !defined(MIJIN_MEMORY_DATA_POOL_HPP_INCLUDED)