├── .gitignore ├── README.md └── flint_arena.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Flint libraries 2 | ========================= 3 | 4 | Public domain single-file header-only C libraries. 5 | 6 | | Library | Version | Description | Dependencies | 7 | |:--------------|:------------|:-------------------------------|:--------------------------| 8 | | flint_arena | 1.0.0 | A simple memory arena. | None | 9 | -------------------------------------------------------------------------------- /flint_arena.h: -------------------------------------------------------------------------------- 1 | // flint_arena: A simple memory arena. 2 | // Version: 1.0.0 3 | // Dependencies: None 4 | // 5 | // VERSION HISTORY 6 | //////////////////////////////////////////////////////////////////////////////// 7 | // 8 | // v1.0.0 (2018-05-13) 9 | // Initial release 10 | // 11 | // INSTRUCTIONS 12 | //////////////////////////////////////////////////////////////////////////////// 13 | // 14 | // To use, write "#define FLINT_ARENA_IMPL" in one of your C files before 15 | // including this file. 16 | // 17 | // EXAMPLE 18 | //////////////////////////////////////////////////////////////////////////////// 19 | #if 0 20 | 21 | #define FLINT_ARENA_IMPL 22 | #include "flint_arena.h" 23 | 24 | // ... 25 | 26 | void * alloc_fn(size_t size) 27 | { 28 | void * ptr = malloc(size); 29 | printf("Allocating %10.d %p\n", (int)size, ptr); 30 | return ptr; 31 | } 32 | 33 | void free_fn(void * ptr) 34 | { 35 | printf("Freeing block %p\n", ptr); 36 | free(ptr); 37 | } 38 | 39 | // ... 40 | 41 | FlArena arena; 42 | fl_arena_init(&arena, alloc_fn, free_fn, 1024 * 1024); 43 | void * my_ptr_1 = fl_arena_alloc(&arena, 200); 44 | void * my_ptr_2 = fl_arena_alloc(&arena, 1234); 45 | fl_arena_free(&arena); 46 | void * my_ptr_3 = fl_arena_alloc(&arena, 1000); 47 | fl_arena_free(&arena); 48 | 49 | #endif 50 | // LICENCE 51 | //////////////////////////////////////////////////////////////////////////////// 52 | // 53 | // This is free and unencumbered software released into the public domain. 54 | // 55 | // Anyone is free to copy, modify, publish, use, compile, sell, or 56 | // distribute this software, either in source code form or as a compiled 57 | // binary, for any purpose, commercial or non-commercial, and by any 58 | // means. 59 | // 60 | // In jurisdictions that recognize copyright laws, the author or authors 61 | // of this software dedicate any and all copyright interest in the 62 | // software to the public domain. We make this dedication for the benefit 63 | // of the public at large and to the detriment of our heirs and 64 | // successors. We intend this dedication to be an overt act of 65 | // relinquishment in perpetuity of all present and future rights to this 66 | // software under copyright law. 67 | // 68 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 69 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 70 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 71 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 72 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 73 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 74 | // OTHER DEALINGS IN THE SOFTWARE. 75 | // 76 | // For more information, please refer to 77 | 78 | #ifndef FLINT_ARENA_DECLS 79 | #define FLINT_ARENA_DECLS 80 | 81 | typedef void * (* FlArenaAllocFn)(size_t); 82 | typedef void (* FlArenaFreeFn)(void *); 83 | 84 | typedef struct FlArena { 85 | char ** blocks; 86 | char * current; 87 | size_t size_left; 88 | FlArenaAllocFn alloc_fn; 89 | FlArenaFreeFn free_fn; 90 | size_t block_size; 91 | } FlArena; 92 | 93 | // Initializes the memory arena. 94 | // 95 | // arena is the FlArena to be allocated. 96 | // All previous states are ignored. 97 | // 98 | // alloc_fn is the memory allocation callback. 99 | // Prototype is void *(size_t size). 100 | // Behavior is undefined if returns NULL. 101 | // 102 | // free_fn is the memory freeing callback. 103 | // Prototype is void(void * ptr). 104 | // 105 | // block_size is the minimum size of the blocks allocated by 106 | // the arena. If a memory region larger than this size is requested, 107 | // a larger block will be allocated. 108 | void fl_arena_init( 109 | FlArena * arena, 110 | FlArenaAllocFn alloc_fn, 111 | FlArenaFreeFn free_fn, 112 | size_t block_size); 113 | 114 | // Allocates a memory region from the arena. 115 | void * fl_arena_alloc(FlArena * arena, size_t size); 116 | 117 | // Frees all blocks allocated by the arena. 118 | // All memory regions previously allocated by fl_arena_alloc 119 | // are subsequently invalid. 120 | void fl_arena_free(FlArena * arena); 121 | 122 | #endif // Decls 123 | 124 | #ifdef FLINT_ARENA_IMPL 125 | 126 | enum { 127 | BLOCK_OVERHEAD = sizeof(char *) 128 | }; 129 | 130 | void fl_arena_init( 131 | FlArena * arena, 132 | FlArenaAllocFn alloc_fn, 133 | FlArenaFreeFn free_fn, 134 | size_t block_size) 135 | { 136 | arena->blocks = 0; 137 | arena->current = 0; 138 | arena->size_left = 0; 139 | arena->alloc_fn = alloc_fn; 140 | arena->free_fn = free_fn; 141 | arena->block_size = block_size; 142 | } 143 | 144 | void * fl_arena_alloc( 145 | FlArena * arena, 146 | size_t size) 147 | { 148 | if (arena->size_left < size) { 149 | size_t block_size = (size < arena->block_size) 150 | ? arena->block_size 151 | : size; 152 | block_size; 153 | 154 | size_t block_node_size = block_size + BLOCK_OVERHEAD; 155 | char ** new_block_node = (char **)arena->alloc_fn(block_node_size); 156 | if (!new_block_node) { 157 | return 0; 158 | } 159 | 160 | *new_block_node = (char *)arena->blocks; 161 | arena->blocks = new_block_node; 162 | 163 | char * new_block = (char *)new_block_node + BLOCK_OVERHEAD; 164 | arena->current = new_block; 165 | arena->size_left = block_size; 166 | } 167 | 168 | void * allocated = arena->current; 169 | arena->size_left -= size; 170 | arena->current += size; 171 | return allocated; 172 | } 173 | 174 | void fl_arena_free(FlArena * arena) 175 | { 176 | char ** block = arena->blocks; 177 | while (block) { 178 | char * next_block = *block; 179 | arena->free_fn(block); 180 | block = (char **)next_block; 181 | } 182 | 183 | arena->blocks = 0; 184 | arena->current = 0; 185 | arena->size_left = 0; 186 | } 187 | 188 | #endif // Impl 189 | --------------------------------------------------------------------------------