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 \
|
-Ialiases \
|
||||||
-Icpath/include \
|
-Icpath/include \
|
||||||
-Idstr/include \
|
-Idstr/include \
|
||||||
|
$(find mem/include/ -type d | xargs -I{} printf "-I{} ") \
|
||||||
"
|
"
|
||||||
SRC="\
|
SRC="\
|
||||||
cpath/src/*.c \
|
cpath/src/*.c \
|
||||||
dstr/src/*.c \
|
dstr/src/*.c \
|
||||||
|
mem/src/*/*.c \
|
||||||
"
|
"
|
||||||
CFLAGS="-shared -fPIC -Wall -Werror -pedantic"
|
CFLAGS="-shared -fPIC -Wall -Werror -pedantic"
|
||||||
OUT="libwizapp.so"
|
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