mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-12 01:36:57 +00:00
filesystem: Add memory arena allocator
I wanted a fast and predictable memory allocator before I start working on the virtual filesystem.
Functions like malloc and realloc will not be used anymore, instead, the allocator will
need to be passed as a function parameter when doing any kind of heap allocation. For example
char* create_string(Memory::Arena *allocator);
int* create_int_array(Memory::Arena *allocator, int size);
The definition MEMORY_CAPACITY in arena.h sets the amount of memory the arena can use.
The number can be increased as needed.
Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
parent
d00414da58
commit
d3c97317ef
2 changed files with 144 additions and 0 deletions
33
core/memory/arena.cpp
Normal file
33
core/memory/arena.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "arena.h"
|
||||||
|
#include "Base/Assert.h"
|
||||||
|
|
||||||
|
Memory::Arena Memory::arena_init() {
|
||||||
|
// TODO(GloriousTaco): The line below is stupidly unsafe. Replace malloc with mmap() and check the return value.
|
||||||
|
auto data =
|
||||||
|
static_cast<uint8_t*>(malloc(sizeof(uint8_t) * MEMORY_CAPACITY));
|
||||||
|
Memory::Arena arena = {
|
||||||
|
.capacity = MEMORY_CAPACITY,
|
||||||
|
.size = 0,
|
||||||
|
.data = data,
|
||||||
|
};
|
||||||
|
return arena;
|
||||||
|
}
|
||||||
|
const uint8_t* Memory::arena_allocate(Memory::Arena* arena,
|
||||||
|
const std::size_t size) {
|
||||||
|
ASSERT(arena != nullptr);
|
||||||
|
ASSERT(arena->size + size < arena->capacity);
|
||||||
|
const uint8_t* const data = &(arena->data[arena->size]);
|
||||||
|
arena->size += size;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
void Memory::arena_reset(Memory::Arena* arena) {
|
||||||
|
ASSERT(arena != nullptr);
|
||||||
|
arena->size = 0;
|
||||||
|
}
|
||||||
|
void Memory::arena_free(Memory::Arena* arena) {
|
||||||
|
ASSERT(arena != nullptr);
|
||||||
|
arena->capacity = 0;
|
||||||
|
arena->size = 0;
|
||||||
|
// TODO(GloriousTaco): Replace free with a memory safe alternative.
|
||||||
|
free(arena->data);
|
||||||
|
}
|
||||||
111
core/memory/arena.h
Normal file
111
core/memory/arena.h
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
#ifndef POUND_ARENA_H
|
||||||
|
#define POUND_ARENA_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
|
||||||
|
/* Defines the default size (in bytes) for memory arenas created via arena_init() */
|
||||||
|
#define MEMORY_CAPACITY 20480 // 20 KB
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME
|
||||||
|
* Arena - Memory management structure for efficient allocation and de-allocation.
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* typedef struct {
|
||||||
|
* std::size_t capacity; Total number of bytes allocated.
|
||||||
|
* std::size_t size; The current number of bytes consumed.
|
||||||
|
* uint8_t* data; A pointer to the base address of the allocated memory buffer.
|
||||||
|
* } Arena;
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The arena struct handles allocating and managing contiguous memory blocks.
|
||||||
|
*
|
||||||
|
* RATIONALE
|
||||||
|
* A memory arena offers a safer alternative to malloc/realloc by
|
||||||
|
* maintaining a single contiguous block eliminates heap fragmentation
|
||||||
|
* that occurs with frequent small allocations.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
std::size_t capacity;
|
||||||
|
std::size_t size;
|
||||||
|
uint8_t* data;
|
||||||
|
} Arena;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME
|
||||||
|
* arena_init - Initialize a memory arena with default capacity.
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* Arena Memory::arena_init();
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The function creates and returns a new memory arena instance with a
|
||||||
|
* pre-allocated capacity. See the definition MEMORY_CAPACITY to change the
|
||||||
|
* default capacity.
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* Returns a valid Arena object on success.
|
||||||
|
*/
|
||||||
|
extern Arena arena_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME
|
||||||
|
* arena_allocate - Allocate memory from a pre-initialized arena.
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* const uint8_t Memory::arena_allocate(Memory::Arena* arena, std::size_t size);
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The function allocates size bytes from the specified arena. It assumes
|
||||||
|
* the arena has sufficient capacity and returns a pointer to the allocated
|
||||||
|
* memory region.
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* Returns a pointer to the first byte of the allocated memory. The returned
|
||||||
|
* pointer is valid until the arena is reset or destroyed.
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
* Requires Arena to be initialized with arena_init() or similar.
|
||||||
|
*/
|
||||||
|
const uint8_t* arena_allocate(Arena* arena, std::size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME
|
||||||
|
* arena_reset - Reset a memory arena's allocation size to zero.
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* void Memory::arena_reset(Memory::Arena* arena);
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The function resets the allocation size of a pre-initialized Arena to zero.
|
||||||
|
* This effectively "frees" all memory allocated from the arena without
|
||||||
|
* deallocating the underlying buffer, allowing reuse of the capacity for
|
||||||
|
* future allocations.
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
* Resets arena->size to 0 while preserving arena->capacity.
|
||||||
|
* Does not free the underlying memory buffer.
|
||||||
|
* Useful for reusing arenas without reallocation.
|
||||||
|
*/
|
||||||
|
void arena_reset(Arena* arena);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NAME
|
||||||
|
* arena_free - Free the memory allocated by an arena
|
||||||
|
*
|
||||||
|
* SYNOPSIS
|
||||||
|
* void Memory::arena_free(Memory::Arena* arena);
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* The function releases the memory buffer associated with a Arena and
|
||||||
|
* resets its capacity and size to zero. This marks the arena as invalid for
|
||||||
|
* future allocation unless reinitialized.
|
||||||
|
*/
|
||||||
|
void arena_free(Memory::Arena* arena);
|
||||||
|
|
||||||
|
} // namespace Memory
|
||||||
|
#endif //POUND_ARENA_H
|
||||||
Loading…
Add table
Add a link
Reference in a new issue