Add per-frame linear memory allocator

This commit is contained in:
Eidolon 2023-10-14 15:17:32 -05:00
parent 43b67be8d5
commit 28f22e3f71
4 changed files with 106 additions and 0 deletions

View file

@ -1,3 +1,5 @@
target_sources(SRB2SDL2 PRIVATE
memory.cpp
memory.h
static_vec.hpp
)

70
src/core/memory.cpp Normal file
View file

@ -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 <array>
#include <new>
#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();
}

31
src/core/memory.h Normal file
View file

@ -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 <stddef.h>
#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__

View file

@ -72,6 +72,7 @@
#include "filesrch.h" // refreshdirmenu
#include "g_input.h" // tutorial mode control scheming
#include "m_perfstats.h"
#include "core/memory.h"
#include "monocypher/monocypher.h"
#include "stun.h"
@ -821,6 +822,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());