// Move into src/Win32.cpp struct OS_System_Info { s32 logical_processor_count; s32 physical_core_count; s32 primary_core_count; s32 secondary_core_count; // Any weaker or "Efficiency" cores. u64 page_size; u64 large_page_size; u64 allocation_granularity; string machine_name; }; struct OS_Process_Info { u32 process_id; b32 large_pages_allowed; string binary_path; string working_path; string user_program_data_path; Array module_load_paths; Array environment_paths; }; struct OS_State_Win32 { Arena* arena; OS_System_Info system_info; OS_Process_Info process_info; }; global OS_State_Win32 os_state_w32; internal b32 win32_g_is_quiet = 0; // No console output internal LONG WINAPI Win32_Exception_Filter (EXCEPTION_POINTERS* exception_ptrs) { if (win32_g_is_quiet) { ExitProcess(1); } static volatile LONG first = 0; if(InterlockedCompareExchange(&first, 1, 0) != 0) { // prevent failures in other threads to popup same message box // this handler just shows first thread that crashes // we are terminating afterwards anyway for (;;) Sleep(1000); } // #TODO: Exception handling code. return 0; } internal void Win32_Entry_Point (int argc, WCHAR **argv) { // See: w32_entry_point_caller(); (raddebugger) SetUnhandledExceptionFilter(&Win32_Exception_Filter); SYSTEM_INFO sysinfo = {0}; GetSystemInfo(&sysinfo); // Try to allow large pages if we can. // b32 large_pages_allowed = 0; // { // HANDLE token; // if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) // { // 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; // large_pages_allowed = !!AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0); // } // CloseHandle(token); // } // } Bootstrap_Main_Thread_Context(); push_arena(get_thread_context()->arena); // #TODO: Need to write Win32 abstraction layer first. { OS_System_Info* info = &os_state_w32.system_info; info->logical_processor_count = (s32)sysinfo.dwNumberOfProcessors; info->page_size = sysinfo.dwPageSize; info->large_page_size = GetLargePageMinimum(); info->allocation_granularity = sysinfo.dwAllocationGranularity; } { OS_Process_Info* info = &os_state_w32.process_info; info->large_pages_allowed = false; info->process_id = GetCurrentProcessId(); } /*{ OS_System_Info* info = &os_state_w32.system_info; // [ ] Extract input args u32 length; GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, (PDWORD)&length); u8* cpu_information_buffer = NewArray(length); GetLogicalProcessorInformationEx(RelationProcessorCore, // *sigh* (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)cpu_information_buffer, (PDWORD)&length); u32 offset = 0; u32 all_cpus_count = 0; u32 max_performance = 0; u32 performance_core_count = 0; // u32 efficient_core_count; while (offset < length) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* cpu_information = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(cpu_information_buffer + offset); offset += cpu_information->Size; u32 count_per_group_physical = 1; u32 value = (u32)cpu_information->Processor.GroupMask->Mask; u32 count_per_group = __popcnt(value); // logical if (cpu_information->Relationship != RelationProcessorCore) continue; if (cpu_information->Processor.EfficiencyClass > max_performance) { max_performance = cpu_information->Processor.EfficiencyClass; performance_core_count = count_per_group_physical; } else if (cpu_information->Processor.EfficiencyClass == max_performance) { performance_core_count += count_per_group_physical; } all_cpus_count += count_per_group; } info->physical_core_count = (s32)all_cpus_count; info->primary_core_count = (s32)performance_core_count; } // info->secondary_core_count = #TODO; */ { OS_System_Info* info = &os_state_w32.system_info; u8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0}; DWORD size = MAX_COMPUTERNAME_LENGTH + 1; if(GetComputerNameA((char*)buffer, &size)) { string machine_name_temp = string(size, buffer); info->machine_name = copy_string(machine_name_temp); } } debug_break(); { OS_Process_Info* info = &os_state_w32.process_info; DWORD length = GetCurrentDirectoryW(0, 0); // This can be freed later when we call temp_reset(); u16* memory = NewArray(get_temp_allocator(), length + 1); length = GetCurrentDirectoryW(length + 1, (WCHAR*)memory); info->working_path = wide_to_utf8(memory, length); Assert(is_valid(info->working_path)); } // [ ] Get Working directory (info->working_path) // [ ] GetEnvironmentStringsW printf("Hello there!\n\n"); // See: main_thread_base_entry_point Main_Entry_Point(argc, argv); }