From c42271c72e798d4c8a34ebda34537e2c5d4c1ea3 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 14 Oct 2023 15:17:32 -0500 Subject: [PATCH] Add per-frame linear memory allocator --- src/CMakeLists.txt | 1 + src/Makefile | 1 + src/blan/internal/CMakeLists.txt | 3 -- src/core/CMakeLists.txt | 1 + src/core/Sourcefile | 1 + src/core/memory.cpp | 70 ++++++++++++++++++++++++++++++++ src/core/memory.h | 31 ++++++++++++++ src/d_main.cpp | 3 ++ 8 files changed, 108 insertions(+), 3 deletions(-) delete mode 100644 src/blan/internal/CMakeLists.txt create mode 100644 src/core/CMakeLists.txt create mode 100644 src/core/Sourcefile create mode 100644 src/core/memory.cpp create mode 100644 src/core/memory.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b95522024..2fbdddaf9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ add_subdirectory(blua) add_subdirectory(blan) add_subdirectory(sdl) add_subdirectory(objects) +add_subdirectory(core) add_subdirectory(acs) # OS macros diff --git a/src/Makefile b/src/Makefile index 6bbcdbe25..4d58e69bd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -220,6 +220,7 @@ sources+=\ $(call List,Sourcefile)\ $(call List,blua/Sourcefile)\ $(call List,blan/Sourcefile)\ + $(call List,core/Sourcefile)\ $(call List,acs/Sourcefile)\ $(call List,acs/ACSVM/Sourcefile)\ $(call List,objects/Sourcefile)\ diff --git a/src/blan/internal/CMakeLists.txt b/src/blan/internal/CMakeLists.txt deleted file mode 100644 index 3242a16be..000000000 --- a/src/blan/internal/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -target_sources(SRB2SDL2 PRIVATE - b_soc.c -) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 000000000..db8bc5a15 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(cpp) diff --git a/src/core/Sourcefile b/src/core/Sourcefile new file mode 100644 index 000000000..752dd7512 --- /dev/null +++ b/src/core/Sourcefile @@ -0,0 +1 @@ +memory.cpp \ No newline at end of file diff --git a/src/core/memory.cpp b/src/core/memory.cpp new file mode 100644 index 000000000..7aebb4768 --- /dev/null +++ b/src/core/memory.cpp @@ -0,0 +1,70 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2023 by Ronald "Eidolon" Kinard +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#include "memory.h" + +#include +#include + +#include "../z_zone.h" + +namespace +{ + +class LinearMemory +{ + size_t size_; + size_t height_; + void* memory_; + +public: + constexpr explicit LinearMemory(size_t size) noexcept; + + void* allocate(size_t size); + void reset() noexcept; +}; + +constexpr LinearMemory::LinearMemory(size_t size) noexcept : size_(size), height_{0}, memory_{nullptr} {} + +void* LinearMemory::allocate(size_t size) +{ + size_t aligned_size = (size + 15) & ~15; + if (height_ + aligned_size > size_) + { + throw std::bad_alloc(); + } + + if (memory_ == nullptr) + { + memory_ = Z_Malloc(size_, PU_STATIC, nullptr); + } + + void* ptr = (void*)((uintptr_t)(memory_) + height_); + height_ += aligned_size; + return ptr; +} + +void LinearMemory::reset() noexcept +{ + height_ = 0; +} + +} // namespace + +static LinearMemory g_frame_memory {4 * 1024 * 1024}; + +void* Z_Frame_Alloc(size_t size) +{ + return g_frame_memory.allocate(size); +} + +void Z_Frame_Reset() +{ + g_frame_memory.reset(); +} diff --git a/src/core/memory.h b/src/core/memory.h new file mode 100644 index 000000000..a1b479b21 --- /dev/null +++ b/src/core/memory.h @@ -0,0 +1,31 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2023 by Ronald "Eidolon" Kinard +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#ifndef __SRB2_CORE_MEMORY_H__ +#define __SRB2_CORE_MEMORY_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cpluspplus + +/// @brief Allocate a block of memory with a lifespan of the current main-thread frame. +/// This function is NOT thread-safe, but the allocated memory may be used across threads. +/// @return a pointer to a block of memory aligned with libc malloc alignment, or null if allocation fails +void* Z_Frame_Alloc(size_t size); + +/// @brief Resets per-frame memory. Not thread safe. +void Z_Frame_Reset(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // __SRB2_CORE_MEMORY_H__ diff --git a/src/d_main.cpp b/src/d_main.cpp index e74764f09..3ac3916c4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -69,6 +69,7 @@ #include "filesrch.h" // refreshdirmenu #include "g_input.h" // tutorial mode control scheming #include "m_perfstats.h" +#include "core/memory.h" // SRB2Kart #include "k_grandprix.h" @@ -756,6 +757,8 @@ void D_SRB2Loop(void) precise_t enterprecise = I_GetPreciseTime(); precise_t finishprecise = enterprecise; + Z_Frame_Reset(); + { // Casting the return value of a function is bad practice (apparently) double budget = round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision());