From 944396128ba02d2a0fae0fda43be8f43d5e3a48a Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Thu, 5 Jan 2023 01:06:55 -0800 Subject: [PATCH] add get core count --- core/os/os_darwin.odin | 12 ++++++++++ core/os/os_freebsd.odin | 13 ++++++++++ core/os/os_linux.odin | 5 ++++ core/os/os_windows.odin | 24 ++++++++++++++++++- core/sys/windows/kernel32.odin | 44 ++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index b40edb410..940003027 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -314,6 +314,7 @@ foreign libc { @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- @(link_name="strerror") _darwin_string_error :: proc(num : c.int) -> cstring --- + @(link_name="sysctlbyname") _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int --- @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- } @@ -771,6 +772,17 @@ get_page_size :: proc() -> int { return page_size } +get_processor_thread_count :: proc() -> int { + count : int = 0 + count_size := size_of(count) + if _sysctlbyname("hw.logicalcpu", rawptr(count), rawptr(count_size), 0, 0) == 0 { + if count > 0 { + return count + } + } + + return 1 +} _alloc_command_line_arguments :: proc() -> []string { res := make([]string, len(runtime.args__)) diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 2a0381a5d..1e2e33810 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -287,6 +287,7 @@ foreign libc { @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- + @(link_name="sysctlbyname") _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int --- @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- } @@ -702,6 +703,18 @@ get_page_size :: proc() -> int { return page_size } +get_processor_thread_count :: proc() -> int { + count : int = 0 + count_size := size_of(count) + if _sysctlbyname("hw.logicalcpu", rawptr(count), rawptr(count_size), 0, 0) == 0 { + if count > 0 { + return count + } + } + + return 1 +} + _alloc_command_line_arguments :: proc() -> []string { res := make([]string, len(runtime.args__)) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index ac40b8cde..acc0d3e1b 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -404,6 +404,7 @@ foreign libc { @(link_name="__errno_location") __errno_location :: proc() -> ^int --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- + @(link_name="get_nprocs") _unix_get_nprocs :: proc() -> c.int --- @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- @@ -878,6 +879,10 @@ get_page_size :: proc() -> int { return page_size } +get_processor_thread_count :: proc() -> int { + thread_count := int(_unix_get_nprocs()) + return thread_count +} _alloc_command_line_arguments :: proc() -> []string { res := make([]string, len(runtime.args__)) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index f48f46fa3..cc01f8cca 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -126,6 +126,28 @@ get_page_size :: proc() -> int { return page_size } +get_processor_thread_count :: proc() -> int { + length : c.int = 0 + result := windows.GetLogicalProcessorInformation(nil, &length) + + thread_count := 0 + if !result && win32.GetLastError() == 122 && length > 0 { + processors := make([]windows.SYSTEM_LOGICAL_PROCESSOR_INFORMATION, length, context.temp_allocator) + + result = windows.GetLogicalProcessorInformation(&processors[0], &length) + if result { + core_count := 0 + for processor in processors { + if processor.Relationship == windows.RelationProcessorCore { + thread := intrinsics.count_ones(processor.ProcessorMask) + thread_count += thread + } + } + } + } + + return thread_count +} exit :: proc "contextless" (code: int) -> ! { @@ -214,4 +236,4 @@ is_windows_10 :: proc() -> bool { is_windows_11 :: proc() -> bool { osvi := get_windows_version_w() return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber >= WINDOWS_11_BUILD_CUTOFF) -} \ No newline at end of file +} diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 3eb42a3ad..1b7e8d397 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -370,6 +370,8 @@ foreign kernel32 { lpTotalNumberOfBytes: PULARGE_INTEGER, lpTotalNumberOfFreeBytes: PULARGE_INTEGER, ) -> BOOL --- + + GetLogicalProcessorInformation :: proc(buffer: ^LOGICAL_PROCESSOR_INFORMATION, returnedLength: PDWORD) -> BOOL --- } @@ -999,3 +1001,45 @@ foreign kernel32 { ConvertThreadToFiber :: proc(lpParameter: LPVOID) -> LPVOID --- SwitchToFiber :: proc(lpFiber: LPVOID) --- } + +LOGICAL_PROCESSOR_RELATIONSHIP :: enum c_int { + RelationProcessorCore, + RelationNumaNode, + RelationCache, + RelationProcessorPackage, + RelationGroup, + RelationProcessorDie, + RelationNumaNodeEx, + RelationProcessorModule, + RelationAll = 0xffff, +} + +PROCESSOR_CACHE_TYPE :: enum c_int { + CacheUnified, + CacheInstruction, + CacheData, + CacheTrace, +} + +CACHE_DESCRIPTOR :: struct { + Level: BYTE, + Associativity: BYTE, + LineSize: WORD, + Size: DWORD, + Type: PROCESSOR_CACHE_TYPE, +} + +SYSTEM_LOGICAL_PROCESSOR_INFORMATION :: struct { + ProcessorMask: ULONGPTR, + Relationship: LOGICAL_PROCESSOR_RELATIONSHIP, + DUMMYUNIONNAME :: union { + ProcessorCore :: struct { + Flags: BYTE, + }, + NumaNode :: struct { + NodeNumber: DWORD, + }, + Cache: CACHE_DESCRIPTOR, + Reserved: [2]ULONGLONG, + }, +}