Musa-Cpp-Lib-V2/src/OS_Win32.cpp

157 lines
5.1 KiB
C++

// 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<string> module_load_paths;
Array<string> 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<u8>(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<u16>(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);
}