diff --git a/CMakeLists.txt b/CMakeLists.txt index ad9c9029..58216a19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -644,6 +644,7 @@ add_executable(${CRYMP_CLIENT_EXE} WIN32 Code/Launcher/MemoryPatch.cpp Code/Launcher/MemoryPatch.h Code/Launcher/Resources.h + Code/Library/BuddyAllocator.h Code/Library/CPUID.cpp Code/Library/CPUID.h Code/Library/CrashLogger.cpp diff --git a/Code/Library/BuddyAllocator.h b/Code/Library/BuddyAllocator.h new file mode 100644 index 00000000..3138a547 --- /dev/null +++ b/Code/Library/BuddyAllocator.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include + +template +class BuddyAllocator +{ + static_assert(std::has_single_bit(ARENA_SIZE_BYTES)); // make sure ARENA_SIZE_BYTES is a power of two + + static constexpr std::size_t SMALLEST_CHUNK_SIZE_BYTES = 16; + + static constexpr std::size_t GetTreeOrder() + { + constexpr std::size_t maxChunkCount = ARENA_SIZE_BYTES / SMALLEST_CHUNK_SIZE_BYTES; + + return (sizeof(std::size_t) * 8) - std::countl_zero(std::bit_ceil(maxChunkCount)); + } + + static constexpr std::size_t GetTreeSize() + { + std::size_t result = 0; + std::size_t multiplier = 1; + for (std::size_t order = GetTreeOrder(); order > 0; order--) + { + result += order * multiplier; + multiplier *= 2; + } + + return result; + } + + static constexpr std::size_t GetTreeUpperPosBound() + { + return 1 << GetTreeOrder(); + } + + std::unique_ptr m_arena = std::make_unique(ARENA_SIZE_BYTES); + std::bitset m_tree; + +public: + void* Allocate(std::size_t bytes) + { + // TODO + return nullptr; + } + + bool Deallocate(void* pointer) + { + std::byte* chunk = static_cast(pointer); + + if (chunk < m_arena.get() || chunk >= (m_arena.get() + ARENA_SIZE_BYTES)) + { + return false; + } + + // TODO + + return true; + } +};