commit 7f814c553b92fa2a7b7dd29b06f9344dd47dd323 parent 01321e760c4a5e25713d1aa0cfec577a12440bfe Author: Michael Savage <mikejsavage@gmail.com> Date: Sun Aug 16 11:56:28 +0200 Add memory arena implementation Diffstat:
intrinsics.h | | | 4 | ++++ |
memory_arena.cc | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
memory_arena.h | | | 26 | ++++++++++++++++++++++++++ |
diff --git a/intrinsics.h b/intrinsics.h @@ -37,11 +37,15 @@ inline void mike_assert( const bool predicate, const char * const message ) { #define assert( predicate ) mike_assert( predicate, "assertion failed at " __FILE__ " line " STRINGIFY( __LINE__ ) ": " #predicate ) #define is_power_of_2( n ) ( ( ( n ) & ( ( n ) - 1 ) ) == 0 ) + #define align_power_of_2( n, alignment ) ( ( ( n ) + ( alignment ) - 1 ) & ~( ( alignment ) - 1 ) ) #define align4( n ) align_power_of_2( n, 4 ) #define align8( n ) align_power_of_2( n, 8 ) #define align16( n ) align_power_of_2( n, 16 ) +// TODO: clashes with some crap in std::string +#define align_TODO( n, alignment ) ( ( ( n ) + ( alignment ) - 1 ) / ( alignment ) * ( alignment ) ) + inline size_t kilobytes( const size_t kb ) { return kb * 1024; } diff --git a/memory_arena.cc b/memory_arena.cc @@ -0,0 +1,42 @@ +#include "intrinsics.h" +#include "memory_arena.h" + +void memarena_init( MemoryArena * const arena, u8 * const memory, const size_t size ) { + arena->memory = memory; + arena->size = size; + arena->used = 0; +} + +u8 * memarena_push_size( MemoryArena * const arena, const size_t size, const size_t alignment ) { + size_t base_index = align_TODO( arena->used, alignment ); + size_t new_used = arena->used + size + ( base_index - arena->used ); + assert( new_used <= arena->size ); + assert( new_used >= arena->used ); + + arena->used = new_used; + + return arena->memory + base_index; +} + +void memarena_clear( MemoryArena * const arena ) { + arena->used = 0; + arena->num_checkpoints = 0; +} + +MemoryArenaCheckpoint memarena_checkpoint( MemoryArena * const arena ) { + MemoryArenaCheckpoint cp = { }; + // cp.arena = arena; + cp.used = arena->used; + arena->num_checkpoints++; + + return cp; +} + +void memarena_restore( MemoryArena * arena, MemoryArenaCheckpoint * const cp ) { + assert( arena->num_checkpoints > 0 ); + assert( !cp->restored ); + + arena->used = cp->used; + arena->num_checkpoints--; + cp->restored = true; +} diff --git a/memory_arena.h b/memory_arena.h @@ -0,0 +1,26 @@ +#ifndef _MEMORY_ARENA_H_ +#define _MEMORY_ARENA_H_ + +#include "intrinsics.h" + +struct MemoryArena { + u8 * memory; + size_t size; + size_t used; + size_t num_checkpoints; +}; + +struct MemoryArenaCheckpoint { + // MemoryArena * arena; + size_t used; + bool restored; +}; + +void memarena_init( MemoryArena * const arena, u8 * const memory, const size_t size ); +u8 * memarena_push_size( MemoryArena * const arena, const size_t size, const size_t alignment = 4 ); +#define memarena_push_type( arena, type ) ( ( type * ) memarena_push_size( arena, sizeof( type ), sizeof( type ) ) ) +void memarena_clear( MemoryArena * const arena ); +MemoryArenaCheckpoint memarena_checkpoint( MemoryArena * const arena ); +void memarena_restore( MemoryArena * arena, MemoryArenaCheckpoint * const cp ); + +#endif // _MEMORY_ARENA_H_