Mercurial > repos > blastem
diff arena.c @ 883:9f149f0e98b7
It is now possible to switch back and forth between the menu ROM and the game
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 13 Nov 2015 19:15:37 -0800 |
parents | |
children | c7c573f0229e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arena.c Fri Nov 13 19:15:37 2015 -0800 @@ -0,0 +1,81 @@ +/* + Copyright 2015 Michael Pavone + This file is part of BlastEm. + BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. +*/ +#include <stdlib.h> +#include <stdint.h> +#include "arena.h" + +struct arena { + void **used_blocks; + void **free_blocks; + + size_t used_count; + size_t used_storage; + size_t free_count; + size_t free_storage; +}; + +static arena *current_arena; + +arena *get_current_arena() +{ + if (!current_arena) { + current_arena = calloc(1, sizeof(arena)); + } + return current_arena; +} + +arena *set_current_arena(arena *a) +{ + arena *tmp = current_arena; + current_arena = a; + return tmp; +} + +arena *start_new_arena() +{ + arena *tmp = current_arena; + current_arena = NULL; + return tmp; +} + +void track_block(void *block) +{ + arena *cur = get_current_arena(); + if (cur->used_count == cur->used_storage) { + cur->used_storage *= 2; + cur->used_blocks = realloc(cur->used_blocks, cur->used_storage * sizeof(void *)); + } + cur->used_blocks[cur->used_count++] = block; +} + +void mark_all_free() +{ + arena *cur = get_current_arena(); + if (!cur->free_blocks) { + cur->free_blocks = cur->used_blocks; + cur->free_storage = cur->used_storage; + cur->free_count = cur->used_count; + cur->used_count = cur->used_storage = 0; + cur->used_blocks = NULL; + } else { + if (cur->free_storage < cur->used_count + cur->free_count) { + cur->free_storage = cur->used_count + cur->free_count; + cur->free_blocks = realloc(cur->free_blocks, cur->free_storage * sizeof(void*)); + } + for (; cur->used_count > 0; cur->used_count--) + { + cur->free_blocks[cur->free_count++] = cur->used_blocks[cur->used_count-1]; + } + } +} + +void *try_alloc_arena() +{ + if (!current_arena || !current_arena->free_count) { + return NULL; + } + return current_arena->free_blocks[--current_arena->free_count]; +}