I think it's fixed now
This commit is contained in:
parent
a29b67e524
commit
e2f0e71003
@ -61,7 +61,19 @@ typedef void* (*Memory_Wipe_Function)(void* memory, u64 byte_count);
|
||||
void* arena_allocator_proc (Allocator_Mode mode, s64 requested_size, s64 old_size, void* old_memory, void* allocator_data);
|
||||
|
||||
// Interface API for normal use (idk how to explain - see Arena_Table.cpp)
|
||||
void initialize_arena_table ();
|
||||
#include <mutex> // #TODO: Replace with Mutex (see OS_Win32.cpp)
|
||||
struct Arena_Table {
|
||||
std::mutex mutex;
|
||||
s32 in_flight_count[6];
|
||||
Array<Arena*> free_table[6];
|
||||
|
||||
#if ARENA_DEBUG
|
||||
Array<Arena*> in_flight[6];
|
||||
#endif
|
||||
b32 initialized;
|
||||
};
|
||||
|
||||
void initialize_arena_table (Allocator allocator);
|
||||
Arena* next_arena (Arena_Reserve reserve_size);
|
||||
void release_arena (Arena* arena, bool delete_extra_pages=true);
|
||||
|
||||
@ -75,6 +87,8 @@ void arena_clear_flags (Arena* arena);
|
||||
void arena_set_bootstrap_flag (Arena* arena);
|
||||
void arena_set_secure_flag (Arena* arena);
|
||||
|
||||
bool arena_is_bootstrapped (Arena* arena);
|
||||
|
||||
void arena_reset_keeping_memory (Arena* arena); // just sets current point to arena_start
|
||||
void arena_reset (Arena* arena); // frees excess pages
|
||||
void arena_reset_overwriting_memory (Arena* arena, Memory_Wipe_Function wipe_function);
|
||||
|
||||
@ -4,64 +4,77 @@
|
||||
// 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
|
||||
global Arena_Table* arena_table;
|
||||
|
||||
void initialize_arena_table () {
|
||||
// debug_break();
|
||||
// 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
|
||||
|
||||
// Only call once from main thread!
|
||||
void initialize_arena_table (Allocator allocator) {
|
||||
Assert(arena_table != nullptr);
|
||||
if (arena_table->initialized)
|
||||
return;
|
||||
|
||||
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);
|
||||
arena_table->in_flight_count[i] = 0;
|
||||
arena_table->free_table[i].allocator = allocator;
|
||||
array_reserve(arena_table->free_table[i], 64);
|
||||
#if ARENA_DEBUG
|
||||
arena_table->in_flight[i].allocator = allocator;
|
||||
array_reserve(arena_table->in_flight[i], 64);
|
||||
#endif
|
||||
}
|
||||
|
||||
arena_tables_initialized = true;
|
||||
arena_table->initialized = true;
|
||||
}
|
||||
|
||||
Arena* next_arena (Arena_Reserve reserve_size) {
|
||||
Assert(arena_table != nullptr);
|
||||
Arena* arena;
|
||||
std::lock_guard<std::mutex> lock(arena_table_mutex);
|
||||
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) {
|
||||
|
||||
if (!arena_table->free_table[reserve_index].count) {
|
||||
arena = bootstrap_arena(reserve_size, ARENA_DEFAULT_COMMIT_PAGE_COUNT);
|
||||
} else {
|
||||
arena = pop(arena_free_table[reserve_index]);
|
||||
arena = pop(arena_table->free_table[reserve_index]);
|
||||
}
|
||||
#if ARENA_DEBUG
|
||||
array_add(arenas_in_flight[reserve_index], arena);
|
||||
array_add(arena_table->in_flight[reserve_index], arena);
|
||||
#endif
|
||||
|
||||
arena_table->in_flight_count[reserve_index] += 1;
|
||||
|
||||
Assert(arena != nullptr);
|
||||
|
||||
return arena;
|
||||
}
|
||||
|
||||
void release_arena (Arena* arena, bool delete_extra_pages) {
|
||||
std::lock_guard<std::mutex> lock(arena_table_mutex);
|
||||
Assert(arena_table != nullptr);
|
||||
Assert(arena != nullptr);
|
||||
Assert(arena_is_bootstrapped(arena));
|
||||
// Only put into free table if arena is bootstrapped?
|
||||
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);
|
||||
array_unordered_remove_by_value(arena_table->in_flight[reserve_index], arena, 1); // BUILD_DEBUG!
|
||||
#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);
|
||||
array_add(arena_table->free_table[reserve_index], arena);
|
||||
|
||||
arenas_in_flight_count[reserve_index] -= 1;
|
||||
|
||||
// #garbage_collection
|
||||
arena_table->in_flight_count[reserve_index] -= 1;
|
||||
/*
|
||||
// #TODO #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) {
|
||||
@ -70,4 +83,5 @@ void release_arena (Arena* arena, bool delete_extra_pages) {
|
||||
// arenas_to_delete_count -= 1;
|
||||
// }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ void platform_init (Arena* arena, s64 new_reserve) {
|
||||
void* address_start =
|
||||
VirtualAlloc(nullptr, (u64)page_aligned_reserve_size, MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
// printf("Reserving range %p:%p (size: %llu)\n", address_start, (u8*)address_start + page_aligned_reserve_size, page_aligned_reserve_size);
|
||||
|
||||
if (address_start == nullptr) {
|
||||
s32 error_code = GetLastError();
|
||||
printf("In Arena:platform_init, VirtualAlloc failed with code %d\n", error_code);
|
||||
@ -24,6 +26,7 @@ void extend_committed_pages (Arena* arena, u8* end) {
|
||||
s64 size = Align_To_Page_Size(delta);
|
||||
|
||||
VirtualAlloc(arena->first_uncommitted_page, (u64)size, MEM_COMMIT, PAGE_READWRITE);
|
||||
// printf("Committing range %p:%p (size: %llu)\n", arena->first_uncommitted_page, (u8*)arena->first_uncommitted_page + size, size);
|
||||
|
||||
// arena_lock_pages(arena, arena->first_uncommitted_page, size);
|
||||
arena->first_uncommitted_page += size;
|
||||
@ -47,7 +50,10 @@ void free_pages_down_to (Arena* arena, s64 pages_to_keep) {
|
||||
u64 bytes_to_decommit = (u64)(arena->first_uncommitted_page - start_address);
|
||||
// arena_unlock_pages(arena, start_address, (s64)bytes_to_decommit);
|
||||
|
||||
VirtualFree(start_address, bytes_to_decommit, MEM_DECOMMIT);
|
||||
if (bytes_to_decommit) {
|
||||
VirtualFree(start_address, bytes_to_decommit, MEM_DECOMMIT);
|
||||
// printf("Freeing pages %p:%p (size: %llu)\n", start_address, (u8*)start_address + bytes_to_decommit, bytes_to_decommit);
|
||||
}
|
||||
|
||||
arena->first_uncommitted_page = start_address;
|
||||
}
|
||||
@ -58,6 +64,9 @@ void arena_delete (Arena* arena) {
|
||||
|
||||
VirtualFree(arena->memory_base, 0, MEM_RELEASE);
|
||||
|
||||
s64 size_tmp = reserve_size(arena);
|
||||
// printf("Releasing range %p:%p (size: %llu)\n", arena->memory_base, (u8*)arena->memory_base + size_tmp, size_tmp);
|
||||
|
||||
if (!arena_was_boostrapped) {
|
||||
arena->memory_base = nullptr;
|
||||
}
|
||||
|
||||
@ -3,8 +3,12 @@
|
||||
internal void Bootstrap_Main_Thread_Context () {
|
||||
// 0. Setup general allocator
|
||||
GPAllocator_Initialize_Allocation_Tracker();
|
||||
|
||||
// 1. Setup arena table
|
||||
initialize_arena_table();
|
||||
arena_table = (Arena_Table*)GPAllocator_New(sizeof(Arena_Table), 64, true); // permanent allocation.
|
||||
memset(arena_table, 0, sizeof(Arena_Table));
|
||||
initialize_arena_table(GPAllocator());
|
||||
|
||||
// 2. Setup thread local context
|
||||
ExpandableArena* arena_ex = expandable_arena_new(Arena_Reserve::Size_64M, 16);
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ void* expandable_arena_alloc (ExpandableArena* arena_ex, s64 byte_count) {
|
||||
Assert(arena_ex != nullptr);
|
||||
Assert(arena_ex->memory_base != nullptr); // must be initialized before calling.
|
||||
Assert(is_valid(arena_ex));
|
||||
Assert(arena_tables_initialized);
|
||||
Assert(arena_table->initialized);
|
||||
|
||||
Arena* arena = (Arena*)arena_ex->current;
|
||||
|
||||
|
||||
@ -103,6 +103,9 @@ void* GPAllocator_New (s64 new_size, s64 alignment, bool initialize) {
|
||||
// _aligned_malloc does not zero memory, so we can zero it here
|
||||
if (initialize && memory) { memset(memory, ALLOCATOR_INIT_VALUE, new_size); }
|
||||
Add_Allocation(new_size, memory, (s32)alignment);
|
||||
|
||||
// printf("[GP] Allocating memory %p of size %llu\n", memory, new_size);
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
@ -121,6 +124,9 @@ void* GPAllocator_Resize (s64 old_size, void* old_memory, s64 new_size, s64 alig
|
||||
}
|
||||
Remove_Allocation(old_memory);
|
||||
Add_Allocation(new_size, new_memory_address, (s32)alignment);
|
||||
|
||||
// printf("[GP] Rellocating memory %p of size %llu\n", new_memory_address, new_size);
|
||||
|
||||
return new_memory_address;
|
||||
}
|
||||
|
||||
@ -128,6 +134,8 @@ void GPAllocator_Delete (void* memory) {
|
||||
if (memory == nullptr) return;
|
||||
Aligned_Free(memory);
|
||||
Remove_Allocation(memory);
|
||||
|
||||
// printf("[GP] Deleting memory %p\n", memory);
|
||||
}
|
||||
|
||||
Allocator GPAllocator () {
|
||||
|
||||
@ -99,8 +99,6 @@ internal void Win32_Entry_Point (int argc, WCHAR **argv) {
|
||||
// }
|
||||
// }
|
||||
|
||||
Bootstrap_Main_Thread_Context();
|
||||
|
||||
push_arena(get_thread_context()->arena);
|
||||
|
||||
{ OS_System_Info* info = &os_state_w32.system_info;
|
||||
|
||||
@ -3,15 +3,16 @@ internal void Main_Entry_Point (int argc, WCHAR **argv);
|
||||
#if OS_WINDOWS
|
||||
#if BUILD_CONSOLE_INTERFACE
|
||||
int wmain(int argc, WCHAR **argv) {
|
||||
Win32_Entry_Point(argc, argv);
|
||||
// See: main_thread_base_entry_point
|
||||
// debug_break();
|
||||
Bootstrap_Main_Thread_Context();
|
||||
// Win32_Entry_Point(argc, argv); // This might be the problem.
|
||||
Main_Entry_Point(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) {
|
||||
Bootstrap_Main_Thread_Context();
|
||||
Win32_Entry_Point(__argc, __wargv);
|
||||
// See: main_thread_base_entry_point
|
||||
Main_Entry_Point(__argc, __wargv);
|
||||
return 0;
|
||||
}
|
||||
@ -188,6 +189,7 @@ void ImGui_Application () {
|
||||
string string_literal_example = "Hello, I am a string literal.";
|
||||
|
||||
internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
||||
// See: main_thread_base_entry_point
|
||||
temp_reset();
|
||||
push_allocator(get_temp_allocator());
|
||||
// tip: use auto_reset or auto_release with `get_thread_context()->arena`
|
||||
@ -207,7 +209,7 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
||||
print_to_builder(sb, "the literal: %s", string_literal_example.data);
|
||||
|
||||
// string result = string_view(sb);
|
||||
auto result = builder_to_string(sb); // also frees
|
||||
string result = builder_to_string(sb); // also frees
|
||||
// print((char*)result.data);
|
||||
log("Hello.");
|
||||
log("log() should automatically append newlines to these prints.");
|
||||
@ -215,7 +217,7 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
||||
log(result);
|
||||
log("Hello. There are %s things here\n", string_literal_example.data);
|
||||
|
||||
print("Hello, I am just a printed message to stdout");
|
||||
print("Hello, I am just a printed message to stdout\n\n");
|
||||
|
||||
// free_string_builder(sb);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user