Compare commits
7 Commits
2be4536850
...
b8db582098
Author | SHA1 | Date | |
---|---|---|---|
b8db582098 | |||
a169fe3654 | |||
9513c05b75 | |||
633632105b | |||
5a0aad5d52 | |||
819d457048 | |||
5cbe7f2612 |
2
compile
2
compile
@ -5,10 +5,12 @@ INCLUDE="\
|
||||
-Ialiases \
|
||||
-Icpath/include \
|
||||
-Idstr/include \
|
||||
$(find mem/include/ -type d | xargs -I{} printf "-I{} ") \
|
||||
"
|
||||
SRC="\
|
||||
cpath/src/*.c \
|
||||
dstr/src/*.c \
|
||||
mem/src/*/*.c \
|
||||
"
|
||||
CFLAGS="-shared -fPIC -Wall -Werror -pedantic"
|
||||
OUT="libwizapp.so"
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
INCLUDE=" \
|
||||
-Ialiases \
|
||||
-Icpath/include \
|
||||
-Idstr/include \
|
||||
"
|
||||
|
||||
SRC=" \
|
||||
cpath/src/*.c \
|
||||
dstr/src/*.c \
|
||||
"
|
15
mem/include/arena/mem_arena.h
Normal file
15
mem/include/arena/mem_arena.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MEM_ARENA_H
|
||||
#define MEM_ARENA_H
|
||||
|
||||
#include "aliases.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct growing_arena Arena;
|
||||
|
||||
bool mem_arena_init(Arena **arena, u64 base_capacity);
|
||||
void *mem_arena_alloc(Arena *arena, u64 size);
|
||||
void *mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
|
||||
void mem_arena_clear(Arena *arena);
|
||||
void mem_arena_free(Arena **arena);
|
||||
|
||||
#endif // !MEM_ARENA_H
|
8
mem/include/util/mem_utils.h
Normal file
8
mem/include/util/mem_utils.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef MEM_UTILS_H
|
||||
#define MEM_UTILS_H
|
||||
|
||||
#include "aliases.h"
|
||||
|
||||
void *mem_util_align_forward(void *ptr, u64 alignment);
|
||||
|
||||
#endif // !MEM_UTILS_H
|
230
mem/src/arena/mem_arena.c
Normal file
230
mem/src/arena/mem_arena.c
Normal file
@ -0,0 +1,230 @@
|
||||
#include "mem_arena.h"
|
||||
#include "aliases.h"
|
||||
#include "mem_utils.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef DEFAULT_ALIGNMENT
|
||||
#define DEFAULT_ALIGNMENT (2 * sizeof(void *))
|
||||
#endif /* ifndef DEFAULT_ALIGNMENT */
|
||||
|
||||
typedef struct base_arena BaseArena;
|
||||
struct base_arena {
|
||||
u8 *buf;
|
||||
u8 *offset;
|
||||
u64 capacity;
|
||||
BaseArena *prev;
|
||||
BaseArena *next;
|
||||
};
|
||||
|
||||
struct growing_arena {
|
||||
BaseArena *active_arena;
|
||||
u64 count;
|
||||
u64 initial_capacity;
|
||||
};
|
||||
|
||||
internal bool base_arena_init(BaseArena *arena, u64 capacity);
|
||||
internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
|
||||
u64 alignment);
|
||||
internal void base_arena_clear(BaseArena *arena);
|
||||
internal void base_arena_free(BaseArena *arena);
|
||||
|
||||
// PUBLIC API
|
||||
|
||||
bool mem_arena_init(Arena **arena, u64 base_capacity) {
|
||||
if (!arena || *arena) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*arena = (Arena *)malloc(sizeof(Arena));
|
||||
Arena *arena_ptr = *arena;
|
||||
if (!arena_ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(arena_ptr, 0, sizeof(Arena));
|
||||
|
||||
arena_ptr->active_arena = (BaseArena *)malloc(sizeof(BaseArena));
|
||||
if (!(arena_ptr->active_arena)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(arena_ptr->active_arena, 0, sizeof(BaseArena));
|
||||
|
||||
if (!base_arena_init(arena_ptr->active_arena, base_capacity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
arena_ptr->count = 1;
|
||||
arena_ptr->initial_capacity = base_capacity;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *mem_arena_alloc(Arena *arena, u64 size) {
|
||||
return mem_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT);
|
||||
}
|
||||
|
||||
void *mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
|
||||
if (!arena || !(arena->active_arena)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
|
||||
if (!output) {
|
||||
if (arena->active_arena->next) {
|
||||
arena->active_arena = arena->active_arena->next;
|
||||
} else {
|
||||
arena->active_arena->next = (BaseArena *)malloc(sizeof(BaseArena));
|
||||
if (!(arena->active_arena->next)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(arena->active_arena->next, 0, sizeof(BaseArena));
|
||||
|
||||
if (!base_arena_init(arena->active_arena->next,
|
||||
arena->initial_capacity)) {
|
||||
free(arena->active_arena->next);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arena->active_arena->next->prev = arena->active_arena;
|
||||
arena->active_arena = arena->active_arena->next;
|
||||
|
||||
++(arena->count);
|
||||
}
|
||||
|
||||
output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
|
||||
if (!output) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memset(output, 0, size);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void mem_arena_clear(Arena *arena) {
|
||||
if (!arena) {
|
||||
return;
|
||||
}
|
||||
|
||||
BaseArena *new_active = NULL;
|
||||
while (arena->active_arena) {
|
||||
base_arena_clear(arena->active_arena);
|
||||
|
||||
arena->active_arena = arena->active_arena->prev;
|
||||
|
||||
if (arena->active_arena) {
|
||||
new_active = arena->active_arena;
|
||||
}
|
||||
}
|
||||
|
||||
arena->active_arena = new_active;
|
||||
}
|
||||
|
||||
void mem_arena_free(Arena **arena) {
|
||||
if (!arena) {
|
||||
return;
|
||||
}
|
||||
|
||||
Arena *arena_ptr = *arena;
|
||||
|
||||
BaseArena *current;
|
||||
BaseArena *next;
|
||||
BaseArena *prev;
|
||||
|
||||
current = arena_ptr->active_arena->next;
|
||||
while (current) {
|
||||
next = current->next;
|
||||
|
||||
base_arena_free(current);
|
||||
free(current);
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
current = arena_ptr->active_arena->prev;
|
||||
while (current) {
|
||||
prev = current->prev;
|
||||
|
||||
base_arena_free(current);
|
||||
free(current);
|
||||
|
||||
current = prev;
|
||||
}
|
||||
|
||||
base_arena_free(arena_ptr->active_arena);
|
||||
|
||||
free(arena_ptr->active_arena);
|
||||
arena_ptr->active_arena = NULL;
|
||||
|
||||
arena_ptr->count = 0;
|
||||
arena_ptr->initial_capacity = 0;
|
||||
|
||||
free(*arena);
|
||||
*arena = NULL;
|
||||
}
|
||||
|
||||
// INTERNAL FUNCTIONS
|
||||
|
||||
internal bool base_arena_init(BaseArena *arena, u64 capacity) {
|
||||
if (!arena || arena->buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 alloc_size = sizeof(u8) * capacity;
|
||||
|
||||
arena->buf = (u8 *)malloc(alloc_size);
|
||||
if (!(arena->buf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(arena->buf, 0, alloc_size);
|
||||
arena->capacity = capacity;
|
||||
arena->offset = arena->buf;
|
||||
arena->prev = arena->next = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
|
||||
u64 alignment) {
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u8 *output = mem_util_align_forward((void *)(arena->offset), alignment);
|
||||
if (output + size >= arena->buf + arena->capacity) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arena->offset += size;
|
||||
|
||||
return (void *)output;
|
||||
}
|
||||
|
||||
internal void base_arena_clear(BaseArena *arena) {
|
||||
if (!arena) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(arena->buf, 0, arena->offset - arena->buf);
|
||||
arena->offset = arena->buf;
|
||||
}
|
||||
|
||||
internal void base_arena_free(BaseArena *arena) {
|
||||
if (!arena) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (arena->buf) {
|
||||
free(arena->buf);
|
||||
}
|
||||
|
||||
arena->buf = arena->offset = NULL;
|
||||
arena->capacity = 0;
|
||||
arena->prev = arena->next = NULL;
|
||||
}
|
28
mem/src/util/mem_utils.c
Normal file
28
mem/src/util/mem_utils.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "mem_utils.h"
|
||||
#include "aliases.h"
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
|
||||
|
||||
void *mem_util_align_forward(void *ptr, u64 alignment) {
|
||||
if (!ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(is_power_of_two(alignment));
|
||||
|
||||
uptr p = (uptr)ptr;
|
||||
uptr align = (uptr)alignment;
|
||||
|
||||
// Similar to p % align, but it's a faster implementation that works fine
|
||||
// because align is guaranteed to be a power of 2
|
||||
uptr modulo = p & (align - 1);
|
||||
|
||||
if (modulo != 0) {
|
||||
p += align - modulo;
|
||||
}
|
||||
|
||||
return (void *)p;
|
||||
}
|
Loading…
Reference in New Issue
Block a user