From 171e25ac76d5e464d460ad839cbd2240e548d503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20W=C3=BCbbers?= Date: Mon, 28 Apr 2025 10:03:09 +0200 Subject: [PATCH] fix memory arena alloc --- src/engine/Shared.h | 5 +++-- src/engine/main.cpp | 5 +++-- src/game/Global.cpp | 34 ++++++++++++++++++++------------ src/game/Global.h | 5 +++-- src/game/Instance.h | 1 - src/game/Level.cpp | 2 +- src/game/Setup.cpp | 12 +++++------ src/game/rendering/Rendering.cpp | 5 +++-- 8 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/engine/Shared.h b/src/engine/Shared.h index 12f21fb..9a1e30f 100644 --- a/src/engine/Shared.h +++ b/src/engine/Shared.h @@ -98,8 +98,9 @@ struct SharedDevData struct MemoryArena { - uint8_t* Ptr = nullptr; - uint64_t Size = 0; + uint8_t* Base = nullptr; + uint64_t Used = 0; + uint64_t MaxSize = 0; uint64_t LastAllocSize = 0; }; diff --git a/src/engine/main.cpp b/src/engine/main.cpp index ce04bd2..6a16b54 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -266,9 +266,10 @@ bool ReloadDLL() void InitMemoryArena(MemoryArena& arena, uint64_t size) { - arena.Size = size; - arena.Ptr = reinterpret_cast( + arena.MaxSize = size; + arena.Base = reinterpret_cast( VirtualAllocEx(GetCurrentProcess(), NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)); + arena.Used = 0; arena.LastAllocSize = 0; } diff --git a/src/game/Global.cpp b/src/game/Global.cpp index 9b00c74..6c5e999 100644 --- a/src/game/Global.cpp +++ b/src/game/Global.cpp @@ -37,21 +37,20 @@ namespace Game GameInst = &instance; } - uint8_t* AllocateScratch(size_t byteCount, size_t align) + uint8_t* AllocateScratch(uint64_t byteCount, uint32_t align) { - size_t offset = GetInstance().UsedScratchAmount; - uint8_t* base = GetShared().Game.TransientArena.Ptr; - uint8_t* current = base + offset; - size_t offsetAligned = ((offset + align - 1) / align) * align; - uint8_t* ptrAligned = base + offsetAligned; - size_t newOffset = offsetAligned + byteCount; - if (newOffset > GetShared().Game.TransientArena.Size) return nullptr; - GetInstance().UsedScratchAmount = newOffset; - GetShared().Game.TransientArena.LastAllocSize = byteCount; + assert(align <= 64); // The alignment of the arena limits the alignment that can be specified here! + auto& arena = GetShared().Game.TransientArena; + uint64_t offsetAligned = ((arena.Used + align - 1) / align) * align; + uint8_t* ptrAligned = arena.Base + offsetAligned; + uint64_t newOffset = offsetAligned + byteCount; + if (newOffset > arena.MaxSize) return nullptr; + arena.Used = newOffset; + arena.LastAllocSize = byteCount; return ptrAligned; } - bool ResizeLastScratchAlloc(size_t newByteCount) + bool ResizeLastScratchAlloc(uint64_t newByteCount) { auto& arena = GetShared().Game.TransientArena; if (newByteCount > arena.LastAllocSize) @@ -59,8 +58,17 @@ namespace Game LOG_ERROR("Can't resize to more than previous size!"); return false; } - arena.Ptr -= arena.LastAllocSize; - arena.Ptr += newByteCount; + LOG("Resizing last allocation from %llu to %llu", arena.LastAllocSize, newByteCount); + arena.Used -= arena.LastAllocSize; + arena.Used += newByteCount; + LOG("New total: %llu", arena.Used); return true; } + + void ResetScratch() + { + auto& arena = GetShared().Game.TransientArena; + arena.Used = 0; + arena.LastAllocSize = 0; + } } // namespace Game diff --git a/src/game/Global.h b/src/game/Global.h index e46ec8b..70f06b4 100644 --- a/src/game/Global.h +++ b/src/game/Global.h @@ -33,6 +33,7 @@ namespace Game void SetShared(SharedData& instance); GameInstance& GetInstance(); void SetInstance(GameInstance& instance); - uint8_t* AllocateScratch(size_t byteCount, size_t align = 16); - bool ResizeLastScratchAlloc(size_t newByteCount); + uint8_t* AllocateScratch(uint64_t byteCount, uint32_t align = 16); + bool ResizeLastScratchAlloc(uint64_t newByteCount); + void ResetScratch(); } // namespace Game diff --git a/src/game/Instance.h b/src/game/Instance.h index f1deecb..b358cbf 100644 --- a/src/game/Instance.h +++ b/src/game/Instance.h @@ -75,7 +75,6 @@ namespace Game { bool IsInitialized = false; uint64_t Size = sizeof(GameInstance); - uint64_t UsedScratchAmount = 0; Time Time; PlayerData Player; Level GameLevel; diff --git a/src/game/Level.cpp b/src/game/Level.cpp index a13c5bf..62c4e04 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -102,7 +102,7 @@ namespace Game void Level::Setup(GameData& data) { LOG("Level setup"); - uint8_t* storagePtr = data.EntityArena.Ptr; + uint8_t* storagePtr = data.EntityArena.Base; bool needReset = false; needReset |= Cubes.Setup(storagePtr, needReset); needReset |= Tests.Setup(storagePtr, needReset); diff --git a/src/game/Setup.cpp b/src/game/Setup.cpp index 9ffe6a1..0338339 100644 --- a/src/game/Setup.cpp +++ b/src/game/Setup.cpp @@ -33,30 +33,30 @@ namespace Game tracy::StartupProfiler(); #endif - if (shared.Game.PermanentArena.Ptr == nullptr) + if (shared.Game.PermanentArena.Base == nullptr) { LOG_ERROR("Game memory not initialized!!"); return; } - if (shared.Game.EntityArena.Ptr == nullptr) + if (shared.Game.EntityArena.Base == nullptr) { LOG_ERROR("Entity memory not initialized!"); return; } - if (shared.Game.PermanentArena.Size < sizeof(GameInstance)) + if (shared.Game.PermanentArena.MaxSize < sizeof(GameInstance)) { - LOG_ERROR("Game memory too small! %u < %u", shared.Game.PermanentArena.Size, sizeof(GameInstance)); + LOG_ERROR("Game memory too small! %u < %u", shared.Game.PermanentArena.MaxSize, sizeof(GameInstance)); return; } - GameInstance& instance = *reinterpret_cast(shared.Game.PermanentArena.Ptr); + GameInstance& instance = *reinterpret_cast(shared.Game.PermanentArena.Base); if (sizeof(GameInstance) != instance.Size) { LOG_WARN("Game instance size changed, resetting!"); instance = {}; } - instance.UsedScratchAmount = 0; SetShared(shared); SetInstance(instance); + ResetScratch(); Puzzle::LoadStaticPuzzleData(); SetupInstance.Rendering.Setup(); instance.GameLevel.Setup(shared.Game); diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index 72f3209..38b1b5a 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -36,13 +36,14 @@ namespace Game constexpr size_t MaxFileSize = ChunkSize * 1024 * 1024; constexpr size_t MaxChunkCount = MaxFileSize / ChunkSize; - bool BufferedFileRead(FILE* file, uint8_t* writePtr, size_t& totalReadCount) + bool BufferedFileRead(FILE* const file, uint8_t* const writePtrIn, size_t& outTotalReadCount) { + uint8_t* writePtr = writePtrIn; for (int32_t i = 0; i < MaxChunkCount; ++i) { size_t readCount = std::fread(writePtr, 1, ChunkSize, file); writePtr += readCount; - totalReadCount += readCount; + outTotalReadCount += readCount; if (readCount != ChunkSize) {