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