Musa-Cpp-Lib-V2/lib/Base/Arena_Table.cpp

74 lines
2.3 KiB
C++

// #TODO: #Arena_Table #garbage_collection in `release_arena`
// [ ] Garbage collection if we have >> 64 in a particular table for a while.
// There should be some parameters regarding what the upper limit for idle
// committed pages should be and a heuristic for maximum number of arenas waiting
// API in Arena.h
#include <mutex> // #TODO: Replace with Mutex (see OS_Win32.cpp)
global b64 arena_tables_initialized = false;
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 () {
// debug_break();
for (s32 i = 0; i < 6; i += 1) {
arena_free_table[i].allocator = GPAllocator();
array_reserve(arena_free_table[i], 64);
#if BUILD_DEBUG
arenas_in_flight[i].allocator = GPAllocator();
array_reserve(arenas_in_flight[i], 64);
#endif
}
arena_tables_initialized = true;
}
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;
// #garbage_collection
if (arena_free_table[reserve_index].count > 64) {
// s64 arenas_to_delete_count = arena_free_table[reserve_index].count - 64.
// while (arenas_to_delete_count > 0) {
// arena_delete(arena_free_table[arena_free_table.count-1]);
// array_unordered_remove_by_index(..);
// arenas_to_delete_count -= 1;
// }
}
}