From 5dd89f350d5a5de26b2a8b2bda002e2de06aa72d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 17 Sep 2024 13:41:56 -0700 Subject: [PATCH] --large_pages option; allow dynamic override of arena defaults --- src/base/base_arena.h | 9 +- src/os/core/os_core.h | 1 + src/os/core/win32/os_core_win32.c | 241 +++++++++++++++--------------- src/raddbg/raddbg_core.c | 8 + 4 files changed, 141 insertions(+), 118 deletions(-) diff --git a/src/base/base_arena.h b/src/base/base_arena.h index f941bcd7..1b0ab394 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -50,12 +50,19 @@ struct Temp U64 pos; }; +//////////////////////////////// +//~ rjf: Global Defaults + +global U64 arena_default_reserve_size = MB(64); +global U64 arena_default_commit_size = KB(64); +global ArenaFlags arena_default_flags = 0; + //////////////////////////////// //~ rjf: Arena Functions //- rjf: arena creation/destruction internal Arena *arena_alloc_(ArenaParams *params); -#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__}) +#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, __VA_ARGS__}) internal void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index dcfb900d..c3f1fdc1 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -24,6 +24,7 @@ typedef struct OS_ProcessInfo OS_ProcessInfo; struct OS_ProcessInfo { U32 pid; + B32 large_pages_allowed; String8 binary_path; String8 initial_path; String8 user_program_data_path; diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index da37a8bc..70a518e9 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1493,129 +1493,60 @@ w32_entry_point_caller(int argc, WCHAR **wargv) { SetUnhandledExceptionFilter(&win32_exception_filter); - //- rjf: do OS layer initialization + //- rjf: dynamically load windows functions which are not guaranteed + // in all SDKs { - // rjf: dynamically load windows functions which are not guaranteed - // in all SDKs + HMODULE module = LoadLibraryA("kernel32.dll"); + w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription"); + FreeLibrary(module); + } + + //- rjf: try to allow large pages if we can + B32 large_pages_allowed = 0; + { + HANDLE token; + if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { - HMODULE module = LoadLibraryA("kernel32.dll"); - w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription"); - FreeLibrary(module); - } - - // rjf: try to enable large pages if we can - { - HANDLE token; - if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) + LUID luid; + if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) { - LUID luid; - if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) - { - TOKEN_PRIVILEGES priv; - priv.PrivilegeCount = 1; - priv.Privileges[0].Luid = luid; - priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0); - } - CloseHandle(token); + TOKEN_PRIVILEGES priv; + priv.PrivilegeCount = 1; + priv.Privileges[0].Luid = luid; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + large_pages_allowed = !!AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0); } + CloseHandle(token); } - - // rjf: get system info - SYSTEM_INFO sysinfo = {0}; - GetSystemInfo(&sysinfo); - - // rjf: set up non-dynamically-alloc'd state - // - // (we need to set up some basics before this layer can supply - // memory allocation primitives) + } + + //- rjf: get system info + SYSTEM_INFO sysinfo = {0}; + GetSystemInfo(&sysinfo); + + //- rjf: set up non-dynamically-alloc'd state + // + // (we need to set up some basics before this layer can supply + // memory allocation primitives) + { + os_w32_state.microsecond_resolution = 1; + LARGE_INTEGER large_int_resolution; + if(QueryPerformanceFrequency(&large_int_resolution)) { - os_w32_state.microsecond_resolution = 1; - LARGE_INTEGER large_int_resolution; - if(QueryPerformanceFrequency(&large_int_resolution)) - { - os_w32_state.microsecond_resolution = large_int_resolution.QuadPart; - } + os_w32_state.microsecond_resolution = large_int_resolution.QuadPart; } - { - OS_SystemInfo *info = &os_w32_state.system_info; - info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors; - info->page_size = sysinfo.dwPageSize; - info->large_page_size = GetLargePageMinimum(); - info->allocation_granularity = sysinfo.dwAllocationGranularity; - } - { - OS_ProcessInfo *info = &os_w32_state.process_info; - info->pid = GetCurrentProcessId(); - } - - // rjf: set up thread context - local_persist TCTX tctx; - tctx_init_and_equip(&tctx); - - // rjf: set up dynamically-alloc'd state - Arena *arena = arena_alloc(); - { - os_w32_state.arena = arena; - { - OS_SystemInfo *info = &os_w32_state.system_info; - U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0}; - DWORD size = MAX_COMPUTERNAME_LENGTH + 1; - if(GetComputerNameA((char*)buffer, &size)) - { - info->machine_name = push_str8_copy(arena, str8(buffer, size)); - } - } - } - { - OS_ProcessInfo *info = &os_w32_state.process_info; - { - Temp scratch = scratch_begin(0, 0); - DWORD size = KB(32); - U16 *buffer = push_array_no_zero(scratch.arena, U16, size); - DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size); - String8 name8 = str8_from_16(scratch.arena, str16(buffer, length)); - String8 name_chopped = str8_chop_last_slash(name8); - info->binary_path = push_str8_copy(arena, name_chopped); - scratch_end(scratch); - } - info->initial_path = os_get_current_path(arena); - { - Temp scratch = scratch_begin(0, 0); - U64 size = KB(32); - U16 *buffer = push_array_no_zero(scratch.arena, U16, size); - if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer))) - { - info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer)); - } - scratch_end(scratch); - } - { - WCHAR *this_proc_env = GetEnvironmentStringsW(); - U64 start_idx = 0; - for(U64 idx = 0;; idx += 1) - { - if(this_proc_env[idx] == 0) - { - if(start_idx == idx) - { - break; - } - else - { - String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); - String8 string = str8_from_16(arena, string16); - str8_list_push(arena, &info->environment, string); - start_idx = idx+1; - } - } - } - } - } - - // rjf: set up entity storage - InitializeCriticalSection(&os_w32_state.entity_mutex); - os_w32_state.entity_arena = arena_alloc(); + } + { + OS_SystemInfo *info = &os_w32_state.system_info; + info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors; + info->page_size = sysinfo.dwPageSize; + info->large_page_size = GetLargePageMinimum(); + info->allocation_granularity = sysinfo.dwAllocationGranularity; + } + { + OS_ProcessInfo *info = &os_w32_state.process_info; + info->large_pages_allowed = large_pages_allowed; + info->pid = GetCurrentProcessId(); } //- rjf: extract arguments @@ -1625,13 +1556,89 @@ w32_entry_point_caller(int argc, WCHAR **wargv) { String16 arg16 = str16_cstring((U16 *)wargv[i]); String8 arg8 = str8_from_16(args_arena, arg16); - if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive)) + if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive) || + str8_match(arg8, str8_lit("-quiet"), StringMatchFlag_CaseInsensitive)) { win32_g_is_quiet = 1; } + if(str8_match(arg8, str8_lit("--large_pages"), StringMatchFlag_CaseInsensitive) || + str8_match(arg8, str8_lit("-large_pages"), StringMatchFlag_CaseInsensitive)) + { + arena_default_flags = ArenaFlag_LargePages; + arena_default_reserve_size = os_w32_state.system_info.large_page_size; + arena_default_commit_size = os_w32_state.system_info.large_page_size; + } argv[i] = (char *)arg8.str; } + //- rjf: set up thread context + local_persist TCTX tctx; + tctx_init_and_equip(&tctx); + + //- rjf: set up dynamically-alloc'd state + Arena *arena = arena_alloc(); + { + os_w32_state.arena = arena; + { + OS_SystemInfo *info = &os_w32_state.system_info; + U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0}; + DWORD size = MAX_COMPUTERNAME_LENGTH + 1; + if(GetComputerNameA((char*)buffer, &size)) + { + info->machine_name = push_str8_copy(arena, str8(buffer, size)); + } + } + } + { + OS_ProcessInfo *info = &os_w32_state.process_info; + { + Temp scratch = scratch_begin(0, 0); + DWORD size = KB(32); + U16 *buffer = push_array_no_zero(scratch.arena, U16, size); + DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size); + String8 name8 = str8_from_16(scratch.arena, str16(buffer, length)); + String8 name_chopped = str8_chop_last_slash(name8); + info->binary_path = push_str8_copy(arena, name_chopped); + scratch_end(scratch); + } + info->initial_path = os_get_current_path(arena); + { + Temp scratch = scratch_begin(0, 0); + U64 size = KB(32); + U16 *buffer = push_array_no_zero(scratch.arena, U16, size); + if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer))) + { + info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer)); + } + scratch_end(scratch); + } + { + WCHAR *this_proc_env = GetEnvironmentStringsW(); + U64 start_idx = 0; + for(U64 idx = 0;; idx += 1) + { + if(this_proc_env[idx] == 0) + { + if(start_idx == idx) + { + break; + } + else + { + String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); + String8 string = str8_from_16(arena, string16); + str8_list_push(arena, &info->environment, string); + start_idx = idx+1; + } + } + } + } + } + + //- rjf: set up entity storage + InitializeCriticalSection(&os_w32_state.entity_mutex); + os_w32_state.entity_arena = arena_alloc(); + //- rjf: call into "real" entry point main_thread_base_entry_point(entry_point, argv, (U64)argc); } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f81bc4da..6acea277 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8371,6 +8371,14 @@ rd_autocomp_lister_item_qsort_compare(RD_AutoCompListerItem *a, RD_AutoCompListe { result = +1; } + else if(a->string.size < b->string.size) + { + result = -1; + } + else if(a->string.size > b->string.size) + { + result = +1; + } else { result = strncmp((char *)a->string.str, (char *)b->string.str, Min(a->string.size, b->string.size));