comparison 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
comparison
equal deleted inserted replaced
882:75453bf2ffac 883:9f149f0e98b7
1 /*
2 Copyright 2015 Michael Pavone
3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include "arena.h"
9
10 struct arena {
11 void **used_blocks;
12 void **free_blocks;
13
14 size_t used_count;
15 size_t used_storage;
16 size_t free_count;
17 size_t free_storage;
18 };
19
20 static arena *current_arena;
21
22 arena *get_current_arena()
23 {
24 if (!current_arena) {
25 current_arena = calloc(1, sizeof(arena));
26 }
27 return current_arena;
28 }
29
30 arena *set_current_arena(arena *a)
31 {
32 arena *tmp = current_arena;
33 current_arena = a;
34 return tmp;
35 }
36
37 arena *start_new_arena()
38 {
39 arena *tmp = current_arena;
40 current_arena = NULL;
41 return tmp;
42 }
43
44 void track_block(void *block)
45 {
46 arena *cur = get_current_arena();
47 if (cur->used_count == cur->used_storage) {
48 cur->used_storage *= 2;
49 cur->used_blocks = realloc(cur->used_blocks, cur->used_storage * sizeof(void *));
50 }
51 cur->used_blocks[cur->used_count++] = block;
52 }
53
54 void mark_all_free()
55 {
56 arena *cur = get_current_arena();
57 if (!cur->free_blocks) {
58 cur->free_blocks = cur->used_blocks;
59 cur->free_storage = cur->used_storage;
60 cur->free_count = cur->used_count;
61 cur->used_count = cur->used_storage = 0;
62 cur->used_blocks = NULL;
63 } else {
64 if (cur->free_storage < cur->used_count + cur->free_count) {
65 cur->free_storage = cur->used_count + cur->free_count;
66 cur->free_blocks = realloc(cur->free_blocks, cur->free_storage * sizeof(void*));
67 }
68 for (; cur->used_count > 0; cur->used_count--)
69 {
70 cur->free_blocks[cur->free_count++] = cur->used_blocks[cur->used_count-1];
71 }
72 }
73 }
74
75 void *try_alloc_arena()
76 {
77 if (!current_arena || !current_arena->free_count) {
78 return NULL;
79 }
80 return current_arena->free_blocks[--current_arena->free_count];
81 }