Mercurial > repos > blastem
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 } |