60 lines
1.7 KiB
C++
60 lines
1.7 KiB
C++
// API in Arena.h
|
|
#include <mutex>
|
|
|
|
global std::mutex arena_table_mutex;
|
|
global s32 arenas_in_flight_count[6];
|
|
global Array<Arena*> arena_free_table[6];
|
|
#if BUILD_DEBUG
|
|
global Array<Arena*> arenas_in_flight[6];
|
|
#endif
|
|
|
|
void initialize_arena_table () {
|
|
for (s32 i = 0; i < 6; i += 1) {
|
|
arena_free_table[i].allocator = GPAllocator();
|
|
arenas_in_flight[i].allocator = GPAllocator();
|
|
array_reserve(arena_free_table[i], 64);
|
|
array_reserve(arenas_in_flight[i], 64);
|
|
}
|
|
}
|
|
|
|
Arena* next_arena (Arena_Reserve reserve_size) {
|
|
Arena* arena;
|
|
std::lock_guard<std::mutex> lock(arena_table_mutex);
|
|
s64 reserve_index = (s64)reserve_size;
|
|
arenas_in_flight_count[reserve_index] += 1;
|
|
if (!arena_free_table[reserve_index].count) {
|
|
arena = bootstrap_arena(reserve_size, ARENA_DEFAULT_COMMIT_PAGE_COUNT);
|
|
} else {
|
|
arena = pop(arena_free_table[reserve_index]);
|
|
}
|
|
#if ARENA_DEBUG
|
|
array_add(arenas_in_flight[reserve_index], arena);
|
|
#endif
|
|
|
|
Assert(arena != nullptr);
|
|
|
|
return arena;
|
|
}
|
|
|
|
void release_arena (Arena* arena, bool delete_extra_pages) {
|
|
std::lock_guard<std::mutex> lock(arena_table_mutex);
|
|
s64 reserve_index = (s64)arena->reserve_size;
|
|
#if ARENA_DEBUG
|
|
array_unordered_remove_by_value(arenas_in_flight[reserve_index], arena, 1);
|
|
#endif
|
|
arena_reset_keeping_memory(arena);
|
|
if (delete_extra_pages) {
|
|
free_pages_down_to(arena, arena->initial_commit_page_count);
|
|
}
|
|
array_add(arena_free_table[reserve_index], arena);
|
|
|
|
arenas_in_flight_count[reserve_index] -= 1;
|
|
|
|
// #TODO: Garbage collection if we have >> 64 in a particular table for a while.
|
|
//
|
|
if (arena_free_table[reserve_index].count > 64) {
|
|
// release some arenas if required
|
|
// arena_delete(...)
|
|
}
|
|
}
|