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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user