| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #ifndef ARENA_H
- #define ARENA_H
- #include <stdint.h>
- #include <stdlib.h>
- typedef uint8_t err_t;
- struct arena_chunk {
- uintptr_t start;
- size_t size;
- };
- struct arena {
- uint8_t *data;
- size_t cur;
- size_t cap;
- struct {
- struct arena_chunk *items;
- size_t size;
- size_t cap;
- } chunks;
- };
- struct arena_err_t {
- struct arena arena;
- err_t err;
- };
- struct arena_void_p_err_t {
- struct arena arena;
- err_t err;
- void *ptr;
- };
- enum arena_err {
- ARENA_ERR_OK = 0,
- ARENA_ERR_MALLOC_FAIL,
- ARENA_ERR_HIT_CAP,
- ARENA_ERR_INVALID_PTR
- };
- struct arena_err_t arena_create(size_t cap);
- err_t arena_destroy(struct arena arena);
- struct arena_void_p_err_t arena_alloc(struct arena arena, size_t size,
- _Bool zero_it);
- struct arena_err_t arena_free(struct arena arena, void *ptr);
- struct arena_err_t arena_forget(struct arena arena, _Bool zero_it);
- err_t arena_dump_chunks(struct arena arena);
- #if defined(ARENA_IMP) || defined(IMP)
- #include <stdlib.h>
- #include <string.h>
- #include "da.h"
- struct arena_err_t
- arena_create(size_t cap)
- {
- void *data = calloc(cap, sizeof(uint8_t));
- if ( data == NULL ) {
- return (struct arena_err_t) { .err = ARENA_ERR_MALLOC_FAIL };
- }
- struct arena arena = {
- .data = data,
- .cap = cap,
- .cur = 0
- };
- DA_CREATE(arena.chunks, sizeof(struct arena_chunk));
- return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
- }
- err_t
- arena_destroy(struct arena arena)
- {
- free(arena.data);
- DA_DESTROY(arena.chunks);
- return ARENA_ERR_OK;
- }
- struct arena_void_p_err_t
- arena_alloc(struct arena arena, size_t size, _Bool zero_it)
- {
- if ( arena.cur + size >= arena.cap ) {
- return (struct arena_void_p_err_t) {
- .arena = arena,
- .ptr = NULL,
- .err = ARENA_ERR_HIT_CAP
- };
- }
- void *ptr = (void *) (arena.data + arena.cur);
- arena.cur += size;
- struct arena_chunk chunk = {
- .start = (uintptr_t) ptr,
- .size = size
- };
- DA_APPEND(arena.chunks, chunk);
- if ( zero_it != 0 ) {
- memset(ptr, 0, size);
- }
- return (struct arena_void_p_err_t) {
- .arena = arena,
- .ptr = ptr,
- .err = ARENA_ERR_OK
- };
- }
- struct arena_err_t
- arena_free(struct arena arena, void *ptr)
- {
- uintptr_t p = (uintptr_t) ptr;
- struct arena_chunk ac = {0};
- _Bool found = 0;
- size_t chunk_index = 0;
- for ( ; chunk_index < arena.chunks.size; ++chunk_index ) {
- ac = arena.chunks.items[chunk_index];
- if ( ac.start == p ) {
- found = 1;
- break;
- }
- }
- if ( found == 0 ) {
- return (struct arena_err_t) {
- .arena = arena,
- .err = ARENA_ERR_INVALID_PTR
- };
- }
- DA_DELETE(arena.chunks, chunk_index);
- return (struct arena_err_t) {
- .arena = arena,
- .err = ARENA_ERR_OK
- };
- }
- struct arena_err_t
- arena_forget(struct arena arena, _Bool zero_it)
- {
- arena.cur = 0;
- if ( zero_it != 0 ) {
- memset(arena.data, 0, arena.cap);
- }
- DA_CLEAR(arena.chunks);
- return (struct arena_err_t) {
- .arena = arena,
- .err = ARENA_ERR_OK
- };
- }
- #include <stdio.h>
- err_t
- arena_dump_chunks(struct arena arena)
- {
- struct arena_chunk ac = {0};
- printf("Allocated Chunks (%li)\n", arena.chunks.size);
- for ( size_t i = 0; i < arena.chunks.size; ++i ) {
- ac = arena.chunks.items[i];
- printf("\tstart: %ld, size: %li\n", ac.start, ac.size);
- }
- return ARENA_ERR_OK;
- }
- #endif /* ARENA_IMP || IMPLEMENTATIONS */
- #endif /* ARENA_H */
|