Compare commits
2 Commits
bc78e4150b
...
ba471f41b7
| Author | SHA1 | Date | |
|---|---|---|---|
| ba471f41b7 | |||
| 99bcba9c4c |
+3
-3
@@ -12,15 +12,15 @@ static MemoryBlock *memoryblock_allocate(U32 size, U32 commit_size, U32 page_siz
|
|||||||
Assert(block != NULL);
|
Assert(block != NULL);
|
||||||
memory_commit(block, commit_size);
|
memory_commit(block, commit_size);
|
||||||
|
|
||||||
|
ASAN_POISON_MEMORY_REGION(block, size);
|
||||||
|
ASAN_UNPOISON_MEMORY_REGION(block, MemoryBlock_Header_Size);
|
||||||
|
|
||||||
block->base = (U8 *)block;
|
block->base = (U8 *)block;
|
||||||
block->size = size;
|
block->size = size;
|
||||||
block->first_free = MemoryBlock_Header_Size;
|
block->first_free = MemoryBlock_Header_Size;
|
||||||
block->arena_offset = 0;
|
block->arena_offset = 0;
|
||||||
block->prev = NULL;
|
block->prev = NULL;
|
||||||
block->committed_end = commit_size;
|
block->committed_end = commit_size;
|
||||||
|
|
||||||
ASAN_POISON_MEMORY_REGION(block->base, block->size);
|
|
||||||
ASAN_UNPOISON_MEMORY_REGION(block, MemoryBlock_Header_Size);
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -1,5 +1,6 @@
|
|||||||
#include "base_core.h"
|
#include "base_core.h"
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
|
#include "mini_arena.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -91,12 +92,12 @@ static void arena_test_2(void)
|
|||||||
((U8*)ptr)[0] = 0x73;
|
((U8*)ptr)[0] = 0x73;
|
||||||
ptr = arena_push(&arena, 0, KB(4));
|
ptr = arena_push(&arena, 0, KB(4));
|
||||||
//((U8*)ptr)[0] = 0x73;
|
//((U8*)ptr)[0] = 0x73;
|
||||||
arena_reset_to(&arena, 1089);
|
// arena_reset_to(&arena, 1089);
|
||||||
arena_dump(&arena);
|
arena_dump(&arena);
|
||||||
arena_reset_to(&arena, 0);
|
arena_reset_to(&arena, 0);
|
||||||
for (U64 i = 0; i < KB(1); i++) {
|
for (U64 i = 0; i < MB(4); i++) {
|
||||||
ptr = arena_push(&arena, MB(1) + 3, 8);
|
ptr = arena_push(&arena, 3, 1);
|
||||||
MemoryZero(ptr, MB(1));
|
MemoryZero(ptr, 3);
|
||||||
}
|
}
|
||||||
arena_free(&arena);
|
arena_free(&arena);
|
||||||
}
|
}
|
||||||
@@ -166,7 +167,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
// arena_test_1();
|
// arena_test_1();
|
||||||
arena_test_2();
|
arena_test_2();
|
||||||
// arena_test_3();
|
arena_test_3();
|
||||||
arena_test_4();
|
arena_test_4();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
-55
@@ -1,96 +1,94 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "base_core.h"
|
#include "base_core.h"
|
||||||
|
|
||||||
typedef struct MiniArena MiniArena;
|
// Mini Arena for arena allocations from a supplied buffer
|
||||||
struct MiniArena {
|
|
||||||
U8 *start; // start of user buffer
|
typedef struct MArena MArena;
|
||||||
U8 *curr; // next alloc point
|
struct MArena {
|
||||||
U8 *end; // one past end of user buffer
|
U8 *base; // start of buffer
|
||||||
int checkpoint_level; // level of miniarenatmp_begin stacks
|
U32 first_free; // next alloc point
|
||||||
|
U32 size;
|
||||||
|
S32 checkpoint_level; // level of marenatmp_begin nesting
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct MiniArenaCheckpoint MiniArenaCheckpoint;
|
typedef struct MArenaCheckpoint MArenaCheckpoint;
|
||||||
struct MiniArenaCheckpoint {
|
struct MArenaCheckpoint {
|
||||||
U8 *alloc_point;
|
U32 offset;
|
||||||
MiniArena *arena;
|
MArena *arena;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LARENA_STATIC_INITIALIZER(data) LARENA_INITIALIZER((data), sizeof(data))
|
#define MARENA_STATIC_INITIALIZER(data) MARENA_INITIALIZER((data), sizeof(data))
|
||||||
#define LARENA_INITIALIZER(data, sz) {.start = (data), .curr = (data), .end = (data) + sz, .checkpoint_level = 0}
|
#define MARENA_INITIALIZER(data, size) {.base = (data), .base = (data), .first_free = 0, .size = (U32)sizeof(data), checkpoint_level = 0}
|
||||||
#define LARENA_DEFINE(var_name, size_, alignment_) \
|
#define MARENA_DEFINE(var_name, size, alignment_) \
|
||||||
struct { \
|
struct { \
|
||||||
_Alignas(alignment_) U8 memory[size_]; \
|
_Alignas(alignment_) U8 memory[size]; \
|
||||||
} var_name##_arena_memory; \
|
} var_name##_arena_memory; \
|
||||||
MiniArena var_name = LARENA_STATIC_INITIALIZER(var_name##_arena_memory.memory)
|
MArena var_name = MARENA_STATIC_INITIALIZER(var_name##_arena_memory.memory)
|
||||||
#define LARENA_ALLOC_TYPE(allocator, type_) miniarenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_))
|
|
||||||
#define LARENA_ALLOC_ARRAY(allocator, type_, nr_elements_) miniarenaalloc_aligned((allocator), (nr_elements_) * sizeof(type_), _Alignof(type_))
|
|
||||||
static INLINE size_t miniarena_size(const MiniArena *arena)
|
|
||||||
|
static INLINE void marena_init(MArena *arena, void *memory, U32 size)
|
||||||
{
|
{
|
||||||
return (size_t)(arena->end - arena->start);
|
Assert(memory != NULL);
|
||||||
|
arena->base = (U8 *)memory;
|
||||||
|
arena->first_free = 0;
|
||||||
|
arena->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE size_t miniarena_used(const MiniArena *arena)
|
static INLINE MArenaCheckpoint marenatmp_begin(MArena *arena)
|
||||||
{
|
{
|
||||||
return (size_t)(arena->curr - arena->start);
|
MArenaCheckpoint checkpoint = {};
|
||||||
}
|
|
||||||
static INLINE size_t miniarena_available(const MiniArena *arena)
|
|
||||||
{
|
|
||||||
return miniarena_size(arena) - miniarena_used(arena);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void miniarena_init(MiniArena *arena, void *memory, size_t sz)
|
|
||||||
{
|
|
||||||
arena->start = arena->curr = (U8 *)memory;
|
|
||||||
arena->end = arena->start + sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE MiniArenaCheckpoint miniarenatmp_begin(MiniArena *arena)
|
|
||||||
{
|
|
||||||
MiniArenaCheckpoint checkpoint = {};
|
|
||||||
|
|
||||||
checkpoint.arena = arena;
|
checkpoint.arena = arena;
|
||||||
checkpoint.alloc_point = arena->curr;
|
checkpoint.offset = arena->first_free;
|
||||||
arena->checkpoint_level++;
|
arena->checkpoint_level++;
|
||||||
|
|
||||||
return checkpoint;
|
return checkpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void miniarenatmp_end(MiniArenaCheckpoint *state)
|
static INLINE void marenatmp_end(MArenaCheckpoint *state)
|
||||||
{
|
{
|
||||||
MiniArena *arena = state->arena;
|
MArena *arena = state->arena;
|
||||||
Assert(arena->checkpoint_level > 0);
|
Assert(arena->checkpoint_level > 0);
|
||||||
arena->curr = state->alloc_point;
|
arena->first_free = state->offset;
|
||||||
arena->checkpoint_level--;
|
arena->checkpoint_level--;
|
||||||
}
|
}
|
||||||
static INLINE void *miniarena_push(MiniArena *arena, size_t sz)
|
|
||||||
|
#define marena_push_type(allocator, type_) marenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_))
|
||||||
|
#define marena_push_array(allocator, type_, nr_elements_) marenaalloc_aligned((allocator), (nr_elements_) * (U32)sizeof(type_), _Alignof(type_))
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE void *marena_push(MArena *arena, U32 size)
|
||||||
{
|
{
|
||||||
if (sz > miniarena_available(arena)) {
|
if (size > arena->size - arena->first_free) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void *start = arena->curr;
|
void *base = &arena->base[arena->first_free];
|
||||||
arena->curr += sz;
|
arena->first_free += size;
|
||||||
return start;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::alloc_align(3)]]
|
[[gnu::alloc_align(3)]]
|
||||||
static INLINE void *miniaren_push_aligned(MiniArena *arena, size_t sz, unsigned int align)
|
static INLINE void *maren_push_aligned(MArena *arena, U32 size, U32 align)
|
||||||
{
|
{
|
||||||
Assert(IsPow2(align));
|
Assert(IsPow2(align));
|
||||||
|
|
||||||
uintptr_t curr = (uintptr_t)arena->curr;
|
U32 aligned = AlignUp(arena->first_free, align);
|
||||||
uintptr_t aligned = AlignUp(curr, align);
|
if (aligned < arena->first_free) { // align wrapped
|
||||||
U8 *start = (U8 *)aligned;
|
|
||||||
|
|
||||||
if (sz > (size_t)(arena->end - start)) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
arena->curr = start + sz;
|
if (aligned > arena->size || size > arena->size - aligned) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return start;
|
void *base = &arena->base[aligned];
|
||||||
|
arena->first_free = aligned + size;
|
||||||
|
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void miniarena_reset(MiniArena *arena)
|
static INLINE void marena_reset(MArena *arena)
|
||||||
{
|
{
|
||||||
arena->curr = arena->start;
|
arena->first_free = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user