diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-05-25 19:43:10 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-25 19:43:10 +0200 |
| commit | 655fab7227fbd92837c82fdbeea65c9121b0f70b (patch) | |
| tree | c7c4b24837d94e140cdef5f5f0458cdf04b0c69a /core | |
| parent | 0a6dced9daf6baa1b2e81b7d5542899ca6022c7e (diff) | |
Add core/hyperthread count for Windows and Linux (#5216)
Add core/hyperthread count to `core:sys/info` for Windows and Linux.
TODO: Linux RISCV, Linux ARM, Darwin, and the BSDs.
Diffstat (limited to 'core')
| -rw-r--r-- | core/crypto/_aes/hw_intel/api.odin | 2 | ||||
| -rw-r--r-- | core/crypto/_chacha20/simd128/chacha20_simd128.odin | 2 | ||||
| -rw-r--r-- | core/crypto/_chacha20/simd256/chacha20_simd256.odin | 2 | ||||
| -rw-r--r-- | core/crypto/sha2/sha2_impl_hw_intel.odin | 2 | ||||
| -rw-r--r-- | core/mem/tlsf/tlsf_internal.odin | 2 | ||||
| -rw-r--r-- | core/sys/freebsd/syscalls.odin | 24 | ||||
| -rw-r--r-- | core/sys/info/cpu_arm.odin | 16 | ||||
| -rw-r--r-- | core/sys/info/cpu_darwin_arm64.odin | 2 | ||||
| -rw-r--r-- | core/sys/info/cpu_intel.odin | 28 | ||||
| -rw-r--r-- | core/sys/info/cpu_linux_arm.odin | 2 | ||||
| -rw-r--r-- | core/sys/info/cpu_linux_intel.odin | 38 | ||||
| -rw-r--r-- | core/sys/info/cpu_linux_riscv64.odin | 4 | ||||
| -rw-r--r-- | core/sys/info/cpu_riscv64.odin | 10 | ||||
| -rw-r--r-- | core/sys/info/cpu_windows.odin | 28 | ||||
| -rw-r--r-- | core/sys/info/doc.odin | 14 | ||||
| -rw-r--r-- | core/sys/windows/kernel32.odin | 3 |
16 files changed, 129 insertions, 50 deletions
diff --git a/core/crypto/_aes/hw_intel/api.odin b/core/crypto/_aes/hw_intel/api.odin index 52669cb35..502d56213 100644 --- a/core/crypto/_aes/hw_intel/api.odin +++ b/core/crypto/_aes/hw_intel/api.odin @@ -6,7 +6,7 @@ import "core:sys/info" // is_supported returns true iff hardware accelerated AES // is supported. is_supported :: proc "contextless" () -> bool { - features, ok := info.cpu_features.? + features, ok := info.cpu.features.? if !ok { return false } diff --git a/core/crypto/_chacha20/simd128/chacha20_simd128.odin b/core/crypto/_chacha20/simd128/chacha20_simd128.odin index cf78541d1..6b37b8d61 100644 --- a/core/crypto/_chacha20/simd128/chacha20_simd128.odin +++ b/core/crypto/_chacha20/simd128/chacha20_simd128.odin @@ -227,7 +227,7 @@ is_performant :: proc "contextless" () -> bool { req_features :: info.CPU_Features{.V} } - features, ok := info.cpu_features.? + features, ok := info.cpu.features.? if !ok { return false } diff --git a/core/crypto/_chacha20/simd256/chacha20_simd256.odin b/core/crypto/_chacha20/simd256/chacha20_simd256.odin index ccb02a947..12fffeb2f 100644 --- a/core/crypto/_chacha20/simd256/chacha20_simd256.odin +++ b/core/crypto/_chacha20/simd256/chacha20_simd256.odin @@ -41,7 +41,7 @@ _VEC_TWO: simd.u64x4 : {2, 0, 2, 0} is_performant :: proc "contextless" () -> bool { req_features :: info.CPU_Features{.avx, .avx2} - features, ok := info.cpu_features.? + features, ok := info.cpu.features.? if !ok { return false } diff --git a/core/crypto/sha2/sha2_impl_hw_intel.odin b/core/crypto/sha2/sha2_impl_hw_intel.odin index f16f353df..cb29a3a20 100644 --- a/core/crypto/sha2/sha2_impl_hw_intel.odin +++ b/core/crypto/sha2/sha2_impl_hw_intel.odin @@ -52,7 +52,7 @@ K_15 :: simd.u64x2{0xa4506ceb90befffa, 0xc67178f2bef9a3f7} // is_hardware_accelerated_256 returns true iff hardware accelerated // SHA-224/SHA-256 is supported. is_hardware_accelerated_256 :: proc "contextless" () -> bool { - features, ok := info.cpu_features.? + features, ok := info.cpu.features.? if !ok { return false } diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index 89b875679..460cc4fb6 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -477,7 +477,7 @@ block_mark_as_free :: proc(block: ^Block_Header) { } @(private, no_sanitize_address) -block_mark_as_used :: proc(block: ^Block_Header, ) { +block_mark_as_used :: proc(block: ^Block_Header) { next := block_next(block) block_set_prev_used(next) block_set_used(block) diff --git a/core/sys/freebsd/syscalls.odin b/core/sys/freebsd/syscalls.odin index 405d1e47c..96fd9ac3f 100644 --- a/core/sys/freebsd/syscalls.odin +++ b/core/sys/freebsd/syscalls.odin @@ -204,21 +204,21 @@ accept_nil :: proc "contextless" (s: Fd) -> (Fd, Errno) { accept :: proc { accept_T, accept_nil } getsockname_or_peername :: proc "contextless" (s: Fd, sockaddr: ^$T, is_peer: bool) -> Errno { - // sockaddr must contain a valid pointer, or this will segfault because - // we're telling the syscall that there's memory available to write to. - addrlen: socklen_t = size_of(T) + // sockaddr must contain a valid pointer, or this will segfault because + // we're telling the syscall that there's memory available to write to. + addrlen: socklen_t = size_of(T) - result, ok := intrinsics.syscall_bsd( - is_peer ? SYS_getpeername : SYS_getsockname, - cast(uintptr)s, - cast(uintptr)sockaddr, - cast(uintptr)&addrlen) + result, ok := intrinsics.syscall_bsd( + is_peer ? SYS_getpeername : SYS_getsockname, + cast(uintptr)s, + cast(uintptr)sockaddr, + cast(uintptr)&addrlen) - if !ok { - return cast(Errno)result - } + if !ok { + return cast(Errno)result + } - return nil + return nil } // Get name of connected peer diff --git a/core/sys/info/cpu_arm.odin b/core/sys/info/cpu_arm.odin index 960e55a56..8f5143394 100644 --- a/core/sys/info/cpu_arm.odin +++ b/core/sys/info/cpu_arm.odin @@ -40,9 +40,13 @@ CPU_Feature :: enum u64 { } CPU_Features :: distinct bit_set[CPU_Feature; u64] - -cpu_features: Maybe(CPU_Features) -cpu_name: Maybe(string) +CPU :: struct { + name: Maybe(string), + features: Maybe(CPU_Features), + physical_cores: int, + logical_cores: int, +} +cpu: CPU @(private) cpu_name_buf: [128]byte @@ -53,7 +57,7 @@ init_cpu_name :: proc "contextless" () { when ODIN_OS == .Darwin { if unix.sysctlbyname("machdep.cpu.brand_string", &cpu_name_buf) { - cpu_name = string(cstring(rawptr(&cpu_name_buf))) + cpu.name = string(cstring(rawptr(&cpu_name_buf))) generic = false } } @@ -61,10 +65,10 @@ init_cpu_name :: proc "contextless" () { if generic { when ODIN_ARCH == .arm64 { copy(cpu_name_buf[:], "ARM64") - cpu_name = string(cpu_name_buf[:len("ARM64")]) + cpu.name = string(cpu_name_buf[:len("ARM64")]) } else { copy(cpu_name_buf[:], "ARM") - cpu_name = string(cpu_name_buf[:len("ARM")]) + cpu.name = string(cpu_name_buf[:len("ARM")]) } } } diff --git a/core/sys/info/cpu_darwin_arm64.odin b/core/sys/info/cpu_darwin_arm64.odin index ffa60d1cb..aaeef9ad9 100644 --- a/core/sys/info/cpu_darwin_arm64.odin +++ b/core/sys/info/cpu_darwin_arm64.odin @@ -5,7 +5,7 @@ import "core:sys/unix" @(init, private) init_cpu_features :: proc "contextless" () { @(static) features: CPU_Features - defer cpu_features = features + defer cpu.features = features try_set :: proc "contextless" (name: cstring, feature: CPU_Feature) -> (ok: bool) { support: b32 diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index c8b8282fe..7c5b38ca4 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -3,12 +3,6 @@ package sysinfo import "base:intrinsics" -// cpuid :: proc(ax, cx: u32) -> (eax, ebc, ecx, edx: u32) --- -cpuid :: intrinsics.x86_cpuid - -// xgetbv :: proc(cx: u32) -> (eax, edx: u32) --- -xgetbv :: intrinsics.x86_xgetbv - CPU_Feature :: enum u64 { aes, // AES hardware implementation (AES NI) adx, // Multi-precision add-carry instruction extensions @@ -49,9 +43,13 @@ CPU_Feature :: enum u64 { } CPU_Features :: distinct bit_set[CPU_Feature; u64] - -cpu_features: Maybe(CPU_Features) -cpu_name: Maybe(string) +CPU :: struct { + name: Maybe(string), + features: Maybe(CPU_Features), + physical_cores: int, // Initialized by cpu_<os>.odin + logical_cores: int, // Initialized by cpu_<os>.odin +} +cpu: CPU @(init, private) init_cpu_features :: proc "c" () { @@ -88,7 +86,7 @@ init_cpu_features :: proc "c" () { when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { // xgetbv is an illegal instruction under FreeBSD 13, OpenBSD 7.1 and NetBSD 10 // return before probing further - cpu_features = set + cpu.features = set return } @@ -151,7 +149,7 @@ init_cpu_features :: proc "c" () { try_set(&set, .rdseed, 18, ebx7) try_set(&set, .adx, 19, ebx7) - cpu_features = set + cpu.features = set } @(private) @@ -179,5 +177,11 @@ init_cpu_name :: proc "c" () { for len(brand) > 0 && brand[len(brand) - 1] == 0 || brand[len(brand) - 1] == ' ' { brand = brand[:len(brand) - 1] } - cpu_name = brand + cpu.name = brand } + +// cpuid :: proc(ax, cx: u32) -> (eax, ebc, ecx, edx: u32) --- +cpuid :: intrinsics.x86_cpuid + +// xgetbv :: proc(cx: u32) -> (eax, edx: u32) --- +xgetbv :: intrinsics.x86_xgetbv
\ No newline at end of file diff --git a/core/sys/info/cpu_linux_arm.odin b/core/sys/info/cpu_linux_arm.odin index 6408decb7..cde76a83d 100644 --- a/core/sys/info/cpu_linux_arm.odin +++ b/core/sys/info/cpu_linux_arm.odin @@ -17,7 +17,7 @@ init_cpu_features :: proc() { if rerr != .NONE || n == 0 { return } features: CPU_Features - defer cpu_features = features + defer cpu.features = features str := string(buf[:n]) for line in strings.split_lines_iterator(&str) { diff --git a/core/sys/info/cpu_linux_intel.odin b/core/sys/info/cpu_linux_intel.odin new file mode 100644 index 000000000..e43737475 --- /dev/null +++ b/core/sys/info/cpu_linux_intel.odin @@ -0,0 +1,38 @@ +#+build i386, amd64 +#+build linux +package sysinfo + +import "core:sys/linux" +import "core:strings" +import "core:strconv" + +@(init, private) +init_cpu_core_count :: proc() { + fd, err := linux.open("/proc/cpuinfo", {}) + if err != .NONE { return } + defer linux.close(fd) + + // This is probably enough right? + buf: [4096]byte + n, rerr := linux.read(fd, buf[:]) + if rerr != .NONE || n == 0 { return } + + str := string(buf[:n]) + for line in strings.split_lines_iterator(&str) { + key, _, value := strings.partition(line, ":") + key = strings.trim_space(key) + value = strings.trim_space(value) + + if key == "cpu cores" { + if num_physical_cores, ok := strconv.parse_int(value); ok { + cpu.physical_cores = num_physical_cores + } + } + + if key == "siblings" { + if num_logical_cores, ok := strconv.parse_int(value); ok { + cpu.logical_cores = num_logical_cores + } + } + } +}
\ No newline at end of file diff --git a/core/sys/info/cpu_linux_riscv64.odin b/core/sys/info/cpu_linux_riscv64.odin index 84f6134d4..3d36d126d 100644 --- a/core/sys/info/cpu_linux_riscv64.odin +++ b/core/sys/info/cpu_linux_riscv64.odin @@ -9,7 +9,7 @@ import "core:sys/linux" @(init, private) init_cpu_features :: proc() { _features: CPU_Features - defer cpu_features = _features + defer cpu.features = _features HWCAP_Bits :: enum u64 { I = 'I' - 'A', @@ -109,5 +109,5 @@ init_cpu_features :: proc() { @(init, private) init_cpu_name :: proc() { - cpu_name = "RISCV64" + cpu.name = "RISCV64" } diff --git a/core/sys/info/cpu_riscv64.odin b/core/sys/info/cpu_riscv64.odin index c3319c48c..64f2edfd3 100644 --- a/core/sys/info/cpu_riscv64.odin +++ b/core/sys/info/cpu_riscv64.odin @@ -95,6 +95,10 @@ CPU_Feature :: enum u64 { } CPU_Features :: distinct bit_set[CPU_Feature; u64] - -cpu_features: Maybe(CPU_Features) -cpu_name: Maybe(string) +CPU :: struct { + name: Maybe(string), + features: Maybe(CPU_Features), + physical_cores: int, + logical_cores: int, +} +cpu: CPU
\ No newline at end of file diff --git a/core/sys/info/cpu_windows.odin b/core/sys/info/cpu_windows.odin new file mode 100644 index 000000000..7dd2d2a8c --- /dev/null +++ b/core/sys/info/cpu_windows.odin @@ -0,0 +1,28 @@ +package sysinfo + +import sys "core:sys/windows" +import "base:intrinsics" + +@(init, private) +init_cpu_core_count :: proc() { + infos: []sys.SYSTEM_LOGICAL_PROCESSOR_INFORMATION + defer delete(infos) + + returned_length: sys.DWORD + // Query for the required buffer size. + if ok := sys.GetLogicalProcessorInformation(raw_data(infos), &returned_length); !ok { + infos = make([]sys.SYSTEM_LOGICAL_PROCESSOR_INFORMATION, returned_length / size_of(sys.SYSTEM_LOGICAL_PROCESSOR_INFORMATION)) + } + + // If it still doesn't work, return + if ok := sys.GetLogicalProcessorInformation(raw_data(infos), &returned_length); !ok { + return + } + + for info in infos { + #partial switch info.Relationship { + case .RelationProcessorCore: cpu.physical_cores += 1 + case .RelationNumaNode: cpu.logical_cores += int(intrinsics.count_ones(info.ProcessorMask)) + } + } +}
\ No newline at end of file diff --git a/core/sys/info/doc.odin b/core/sys/info/doc.odin index 2fd34b864..aef444f98 100644 --- a/core/sys/info/doc.odin +++ b/core/sys/info/doc.odin @@ -26,13 +26,15 @@ Example: import si "core:sys/info" main :: proc() { - fmt.printfln("Odin: %v", ODIN_VERSION) - fmt.printfln("OS: %v", si.os_version.as_string) - fmt.printfln("OS: %#v", si.os_version) - fmt.printfln("CPU: %v", si.cpu_name) - fmt.printfln("RAM: %#.1M", si.ram.total_ram) + fmt.printfln("Odin: %v", ODIN_VERSION) + fmt.printfln("OS: %v", si.os_version.as_string) + fmt.printfln("OS: %#v", si.os_version) + fmt.printfln("CPU: %v", si.cpu.name) + fmt.printfln("CPU: %v", si.cpu.name) + fmt.printfln("CPU cores: %vc/%vt", si.cpu.physical_cores, si.cpu.logical_cores) + fmt.printfln("RAM: %#.1M", si.ram.total_ram) - // fmt.printfln("Features: %v", si.cpu_features) + // fmt.printfln("Features: %v", si.cpu.features) // fmt.printfln("MacOS version: %v", si.macos_version) fmt.println() diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 266dcdbf4..ed32c7a9f 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -857,7 +857,6 @@ MEMORY_RESOURCE_NOTIFICATION_TYPE :: enum c_int { LowMemoryResourceNotification :: MEMORY_RESOURCE_NOTIFICATION_TYPE.LowMemoryResourceNotification HighMemoryResourceNotification :: MEMORY_RESOURCE_NOTIFICATION_TYPE.HighMemoryResourceNotification - @(default_calling_convention="system") foreign kernel32 { CreateMemoryResourceNotification :: proc( @@ -1194,7 +1193,7 @@ DUMMYUNIONNAME_u :: struct #raw_union { SYSTEM_LOGICAL_PROCESSOR_INFORMATION :: struct { ProcessorMask: ULONG_PTR, Relationship: LOGICAL_PROCESSOR_RELATIONSHIP, - DummyUnion: DUMMYUNIONNAME_u, + using DummyUnion: DUMMYUNIONNAME_u, } SYSTEM_POWER_STATUS :: struct { |