1 #include <bz/memory/arena_internal.h>
3 #include <bz/memory/allocator.h>
6 #include <string.h> // memset... :rolleyes:
8 /*struct BZExpandedPointer {
12 typedef struct BZExpandedPointer BZExpandedPointer;*/
14 //const size_t kMaxUserArenas = 32;
15 #define kMaxUserArenas 32 // FIXME
16 static BZMemoryArena userArenas[kMaxUserArenas];
17 static size_t nextUserArena = 0;
19 BZMemoryArenaID kBZSystemMemoryArena = &userArenas[0];
21 static size_t allocateSize(size_t size) {
22 size_t alignment = alignof(max_align_t); // FIXME, check this alignment stuff...
23 size_t alignmentPadding = (alignment - (size % alignment)) % alignment;
24 size_t fullSize = size + alignmentPadding;// + sizeof(BZExpandedPointer);
28 BZMemoryArenaID bzMemoryArenaCreate(BZMemoryArenaID hostArena, size_t size, const char *nameFmt, ...) {
29 bzAssert(size == allocateSize(size));
30 if (nextUserArena < kMaxUserArenas) {
31 return bzMemoryArenaAllocate(&userArenas[++nextUserArena], hostArena, size);
33 bzError("Too many arenas");
38 void bzMemoryArenaReset(BZMemoryArenaID arena) {
39 bzMemoryArenaSetup(arena, arena->memory, arena->maxSize, arena->zeroOut);
42 void bzMemoryArenaResetTmp(BZMemoryArenaID arena) {
44 memset(&arena->memory[arena->maxSize - arena->allocationOffsetTop], 0, arena->allocationOffsetTop);
46 arena->allocationOffsetTop = 0;
49 BZMemoryArenaID bzMemoryArenaSetup(BZMemoryArena *arenaOut, void *memory, size_t size, bool zeroOut) {
50 arenaOut->maxSize = size;
51 arenaOut->memory = memory;
52 arenaOut->numWatermarks = 0;
53 arenaOut->zeroOut = zeroOut;
55 arenaOut->allocationOffsetBottom = 0;
56 arenaOut->allocationOffsetTop = 0;
58 if (arenaOut->zeroOut) {
59 // We're gonna interop with C++, so we really need to do this.
60 memset(memory, 0, size);
66 BZMemoryArenaID bzMemoryArenaAllocate(BZMemoryArena *arenaOut, BZMemoryArenaID arenaFrom, size_t size) {
67 void *memory = bzMemoryAlloc(arenaFrom, size);
68 return bzMemoryArenaSetup(arenaOut, memory, size, true);
71 void bzMemoryArenaPushWatermark(BZMemoryArenaID arena) {
72 if (arena->numWatermarks < MAX_WATERMARKS) {
73 arena->watermarks[arena->numWatermarks++] = arena->allocationOffsetBottom;
75 bzError("Watermarked too many times!!");
79 void bzMemoryArenaPopWatermark(BZMemoryArenaID arena) {
80 if (arena->numWatermarks > 0) {
81 size_t lastAllocation = arena->allocationOffsetBottom;
82 arena->allocationOffsetBottom = arena->watermarks[--arena->numWatermarks];
85 // We're gonna interop with C++, so we really need to do this.
86 // Zero out anything that got used.
87 memset(&arena->memory[arena->allocationOffsetBottom], 0, lastAllocation - arena->allocationOffsetBottom);
90 bzError("Watermarked too many times!!");
94 void *_bzMemoryAlloc(BZMemoryArenaID arena, size_t size, const char *filename, size_t lineNumber) {
95 bzAssertMessage(arena != NULL, "No memory arena");
97 size_t fullSize = allocateSize(size);
100 if (arena == kBZSystemMemoryArena) {
101 ptr = bzSystemAllocate(fullSize);
102 // if (arena->zeroOut) {
103 memset(ptr, 0, fullSize); // Just do this one...
105 } else if (arena->allocationOffsetBottom + fullSize <= arena->maxSize - arena->allocationOffsetTop) {
106 ptr = &arena->memory[arena->allocationOffsetBottom];
107 arena->allocationOffsetBottom += fullSize;
110 bzAssertMessage(ptr != NULL, "Arena is out of memory, failed %s:%d", filename, lineNumber);
115 void *_bzMemoryAllocTmp(BZMemoryArenaID arena, size_t size, const char *filename, size_t lineNumber) {
116 bzAssertMessage(arena != NULL, "No memory arena");
118 size_t fullSize = allocateSize(size);
121 if (arena == kBZSystemMemoryArena) {
122 ptr = bzSystemAllocateStack(fullSize);
123 } else if (arena->maxSize - arena->allocationOffsetTop - fullSize >= arena->allocationOffsetBottom) {
124 arena->allocationOffsetTop += fullSize;
125 ptr = &arena->memory[arena->maxSize - arena->allocationOffsetTop];
128 bzAssertMessage(ptr != NULL, "Arena is out of memory, failed %s:%d", filename, lineNumber);
131 } // FIXME, this won't work if you pass arena to other places, need more watermarking??....
134 //void bzMemoryFree(void *p) {
136 // ptr -= sizeof(BZExpandedPointer);
138 // if (*(BZMemoryArenaID *)ptr == kBZSystemMemoryArena) {
141 // bzLog("Asked to free arena memory that cannot be");