mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-04 12:07:45 +00:00
Merge pull request #3518 from laytan/sysinfo-arm-additions
sys/info: add arm feature detection, fix Linux implementation, show more CPU info on Darwin
This commit is contained in:
@@ -337,7 +337,7 @@ syscall_ftruncate :: #force_inline proc "contextless" (fd: c.int, length: off_t)
|
||||
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.ftruncate), uintptr(fd), uintptr(length))
|
||||
}
|
||||
|
||||
syscall_sysctl :: #force_inline proc "contextless" (name: ^c.int, namelen: c.uint, oldp: rawptr, oldlenp: ^i64, newp: ^i8, newlen: i64) -> c.int {
|
||||
syscall_sysctl :: #force_inline proc "contextless" (name: [^]c.int, namelen: c.size_t, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> c.int {
|
||||
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctl), uintptr(name), uintptr(namelen), uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
|
||||
}
|
||||
|
||||
@@ -390,8 +390,8 @@ syscall_adjtime :: #force_inline proc "contextless" (delta: ^timeval, old_delta:
|
||||
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.adjtime), uintptr(delta), uintptr(old_delta))
|
||||
}
|
||||
|
||||
syscall_sysctlbyname :: #force_inline proc "contextless" (name: cstring, oldp: rawptr, oldlenp: ^i64, newp: rawptr, newlen: i64) -> c.int {
|
||||
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctlbyname), transmute(uintptr)name, uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
|
||||
syscall_sysctlbyname :: #force_inline proc "contextless" (name: string, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> c.int {
|
||||
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctlbyname), uintptr(raw_data(name)), uintptr(len(name)), uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
|
||||
}
|
||||
|
||||
syscall_proc_info :: #force_inline proc "contextless" (num: c.int, pid: u32, flavor: c.int, arg: u64, buffer: rawptr, buffer_size: c.int) -> c.int {
|
||||
|
||||
@@ -1,26 +1,70 @@
|
||||
//+build arm32, arm64
|
||||
package sysinfo
|
||||
|
||||
// TODO: Set up an enum with the ARM equivalent of the above.
|
||||
CPU_Feature :: enum u64 {}
|
||||
import "core:sys/unix"
|
||||
|
||||
cpu_features: Maybe(CPU_Feature)
|
||||
cpu_name: Maybe(string)
|
||||
_ :: unix
|
||||
|
||||
@(init, private)
|
||||
init_cpu_features :: proc "c" () {
|
||||
CPU_Feature :: enum u64 {
|
||||
// Advanced SIMD & floating-point capabilities:
|
||||
asimd, // General support for Advanced SIMD instructions/neon.
|
||||
floatingpoint, // General support for floating-point instructions.
|
||||
asimdhp, // Advanced SIMD half-precision conversion instructions.
|
||||
bf16, // Storage and arithmetic instructions of the Brain Floating Point (BFloat16) data type.
|
||||
fcma, // Floating-point complex number instructions.
|
||||
fhm, // Floating-point half-precision multiplication instructions.
|
||||
fp16, // General half-precision floating-point data processing instructions.
|
||||
frint, // Floating-point to integral valued floating-point number rounding instructions.
|
||||
i8mm, // Advanced SIMD int8 matrix multiplication instructions.
|
||||
jscvt, // JavaScript conversion instruction.
|
||||
rdm, // Advanced SIMD rounding double multiply accumulate instructions.
|
||||
|
||||
flagm, // Condition flag manipulation instructions.
|
||||
flagm2, // Enhancements to condition flag manipulation instructions.
|
||||
crc32, // CRC32 instructions.
|
||||
|
||||
lse, // Atomic instructions to support large systems.
|
||||
lse2, // Changes to single-copy atomicity and alignment requirements for loads and stores for large systems.
|
||||
lrcpc, // Load-acquire Release Consistency processor consistent (RCpc) instructions.
|
||||
lrcpc2, // Load-acquire Release Consistency processor consistent (RCpc) instructions version 2.
|
||||
|
||||
aes,
|
||||
pmull,
|
||||
sha1,
|
||||
sha256,
|
||||
sha512,
|
||||
sha3,
|
||||
|
||||
sb, // Barrier instruction to control speculation.
|
||||
ssbs, // Instructions to control speculation of loads and stores.
|
||||
}
|
||||
|
||||
CPU_Features :: distinct bit_set[CPU_Feature; u64]
|
||||
|
||||
cpu_features: Maybe(CPU_Features)
|
||||
cpu_name: Maybe(string)
|
||||
|
||||
@(private)
|
||||
_cpu_name_buf: [72]u8
|
||||
cpu_name_buf: [128]byte
|
||||
|
||||
@(init, private)
|
||||
init_cpu_name :: proc "c" () {
|
||||
when ODIN_ARCH == .arm32 {
|
||||
copy(_cpu_name_buf[:], "ARM")
|
||||
cpu_name = string(_cpu_name_buf[:3])
|
||||
} else {
|
||||
copy(_cpu_name_buf[:], "ARM64")
|
||||
cpu_name = string(_cpu_name_buf[:5])
|
||||
init_cpu_name :: proc "contextless" () {
|
||||
generic := true
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
if unix.sysctlbyname("machdep.cpu.brand_string", &cpu_name_buf) {
|
||||
cpu_name = string(cstring(rawptr(&cpu_name_buf)))
|
||||
generic = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if generic {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
copy(cpu_name_buf[:], "ARM64")
|
||||
cpu_name = string(cpu_name_buf[:len("ARM64")])
|
||||
} else {
|
||||
copy(cpu_name_buf[:], "ARM")
|
||||
cpu_name = string(cpu_name_buf[:len("ARM")])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
98
core/sys/info/cpu_darwin_arm64.odin
Normal file
98
core/sys/info/cpu_darwin_arm64.odin
Normal file
@@ -0,0 +1,98 @@
|
||||
package sysinfo
|
||||
|
||||
import "core:sys/unix"
|
||||
|
||||
@(init, private)
|
||||
init_cpu_features :: proc "contextless" () {
|
||||
@(static) features: CPU_Features
|
||||
defer cpu_features = features
|
||||
|
||||
try_set :: proc "contextless" (name: string, feature: CPU_Feature) -> (ok: bool) {
|
||||
support: b32
|
||||
if ok = unix.sysctlbyname(name, &support); ok && support {
|
||||
features += { feature }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Docs from Apple: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
|
||||
// Features from there that do not have (or I didn't find) an equivalent on Linux are commented out below.
|
||||
|
||||
// Advanced SIMD & floating-point capabilities:
|
||||
{
|
||||
if !try_set("hw.optional.AdvSIMD", .asimd) {
|
||||
try_set("hw.optional.neon", .asimd)
|
||||
}
|
||||
|
||||
try_set("hw.optional.floatingpoint", .floatingpoint)
|
||||
|
||||
if !try_set("hw.optional.AdvSIMD_HPFPCvt", .asimdhp) {
|
||||
try_set("hw.optional.neon_hpfp", .asimdhp)
|
||||
}
|
||||
|
||||
try_set("hw.optional.arm.FEAT_BF16", .bf16)
|
||||
// try_set("hw.optional.arm.FEAT_DotProd", .dotprod)
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_FCMA", .fcma) {
|
||||
try_set("hw.optional.armv8_3_compnum", .fcma)
|
||||
}
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_FHM", .fhm) {
|
||||
try_set("hw.optional.armv8_2_fhm", .fhm)
|
||||
}
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_FP16", .fp16) {
|
||||
try_set("hw.optional.neon_fp16", .fp16)
|
||||
}
|
||||
|
||||
try_set("hw.optional.arm.FEAT_FRINTTS", .frint)
|
||||
try_set("hw.optional.arm.FEAT_I8MM", .i8mm)
|
||||
try_set("hw.optional.arm.FEAT_JSCVT", .jscvt)
|
||||
try_set("hw.optional.arm.FEAT_RDM", .rdm)
|
||||
}
|
||||
|
||||
// Integer capabilities:
|
||||
{
|
||||
try_set("hw.optional.arm.FEAT_FlagM", .flagm)
|
||||
try_set("hw.optional.arm.FEAT_FlagM2", .flagm2)
|
||||
try_set("hw.optional.armv8_crc32", .crc32)
|
||||
}
|
||||
|
||||
// Atomic and memory ordering instruction capabilities:
|
||||
{
|
||||
try_set("hw.optional.arm.FEAT_LRCPC", .lrcpc)
|
||||
try_set("hw.optional.arm.FEAT_LRCPC2", .lrcpc2)
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_LSE", .lse) {
|
||||
try_set("hw.optional.armv8_1_atomics", .lse)
|
||||
}
|
||||
|
||||
// try_set("hw.optional.arm.FEAT_LSE2", .lse2)
|
||||
}
|
||||
|
||||
// Encryption capabilities:
|
||||
{
|
||||
try_set("hw.optional.arm.FEAT_AES", .aes)
|
||||
try_set("hw.optional.arm.FEAT_PMULL", .pmull)
|
||||
try_set("hw.optional.arm.FEAT_SHA1", .sha1)
|
||||
try_set("hw.optional.arm.FEAT_SHA256", .sha256)
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_SHA512", .sha512) {
|
||||
try_set("hw.optional.armv8_2_sha512", .sha512)
|
||||
}
|
||||
|
||||
if !try_set("hw.optional.arm.FEAT_SHA3", .sha3) {
|
||||
try_set("hw.optional.armv8_2_sha3", .sha3)
|
||||
}
|
||||
}
|
||||
|
||||
// General capabilities:
|
||||
{
|
||||
// try_set("hw.optional.arm.FEAT_BTI", .bti)
|
||||
// try_set("hw.optional.arm.FEAT_DPB", .dpb)
|
||||
// try_set("hw.optional.arm.FEAT_DPB2", .dpb2)
|
||||
// try_set("hw.optional.arm.FEAT_ECV", .ecv)
|
||||
try_set("hw.optional.arm.FEAT_SB", .sb)
|
||||
try_set("hw.optional.arm.FEAT_SSBS", .ssbs)
|
||||
}
|
||||
}
|
||||
65
core/sys/info/cpu_linux_arm.odin
Normal file
65
core/sys/info/cpu_linux_arm.odin
Normal file
@@ -0,0 +1,65 @@
|
||||
//+build arm32, arm64
|
||||
//+build linux
|
||||
package sysinfo
|
||||
|
||||
import "core:sys/linux"
|
||||
import "core:strings"
|
||||
|
||||
@(init, private)
|
||||
init_cpu_features :: 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 }
|
||||
|
||||
features: CPU_Features
|
||||
defer cpu_features = features
|
||||
|
||||
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 != "Features" { continue }
|
||||
|
||||
for feature in strings.split_by_byte_iterator(&value, ' ') {
|
||||
switch feature {
|
||||
case "asimd", "neon": features += { .asimd }
|
||||
case "fp": features += { .floatingpoint }
|
||||
case "asimdhp": features += { .asimdhp }
|
||||
case "asimdbf16": features += { .bf16 }
|
||||
case "fcma": features += { .fcma }
|
||||
case "asimdfhm": features += { .fhm }
|
||||
case "fphp", "half": features += { .fp16 }
|
||||
case "frint": features += { .frint }
|
||||
case "i8mm": features += { .i8mm }
|
||||
case "jscvt": features += { .jscvt }
|
||||
case "asimdrdm": features += { .rdm }
|
||||
|
||||
case "flagm": features += { .flagm }
|
||||
case "flagm2": features += { .flagm2 }
|
||||
case "crc32": features += { .crc32 }
|
||||
|
||||
case "atomics": features += { .lse }
|
||||
case "lrcpc": features += { .lrcpc }
|
||||
case "ilrcpc": features += { .lrcpc2 }
|
||||
|
||||
case "aes": features += { .aes }
|
||||
case "pmull": features += { .pmull }
|
||||
case "sha1": features += { .sha1 }
|
||||
case "sha2": features += { .sha256 }
|
||||
case "sha3": features += { .sha3 }
|
||||
case "sha512": features += { .sha512 }
|
||||
|
||||
case "sb": features += { .sb }
|
||||
case "ssbs": features += { .ssbs }
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -19,18 +19,21 @@ Example:
|
||||
import si "core:sys/info"
|
||||
|
||||
main :: proc() {
|
||||
fmt.printf("Odin: %v\n", ODIN_VERSION)
|
||||
fmt.printf("OS: %v\n", si.os_version.as_string)
|
||||
fmt.printf("OS: %#v\n", si.os_version)
|
||||
fmt.printf("CPU: %v\n", si.cpu_name)
|
||||
fmt.printf("RAM: %v MiB\n", si.ram.total_ram / 1024 / 1024)
|
||||
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("Features: %v", si.cpu_features)
|
||||
// fmt.printfln("MacOS version: %v", si.macos_version)
|
||||
|
||||
fmt.println()
|
||||
for gpu, i in si.gpus {
|
||||
fmt.printf("GPU #%v:\n", i)
|
||||
fmt.printf("\tVendor: %v\n", gpu.vendor_name)
|
||||
fmt.printf("\tModel: %v\n", gpu.model_name)
|
||||
fmt.printf("\tVRAM: %v MiB\n", gpu.total_ram / 1024 / 1024)
|
||||
fmt.printfln("GPU #%v:", i)
|
||||
fmt.printfln("\tVendor: %v", gpu.vendor_name)
|
||||
fmt.printfln("\tModel: %v", gpu.model_name)
|
||||
fmt.printfln("\tVRAM: %#.1M", gpu.total_ram)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,11 +54,11 @@ Example:
|
||||
as_string = "Windows 10 Professional (version: 20H2), build: 19042.1466",
|
||||
}
|
||||
CPU: AMD Ryzen 7 1800X Eight-Core Processor
|
||||
RAM: 65469 MiB
|
||||
RAM: 64.0 GiB
|
||||
GPU #0:
|
||||
Vendor: Advanced Micro Devices, Inc.
|
||||
Model: Radeon RX Vega
|
||||
VRAM: 8176 MiB
|
||||
VRAM: 8.0 GiB
|
||||
|
||||
- Example macOS output:
|
||||
|
||||
@@ -73,6 +76,6 @@ Example:
|
||||
as_string = "macOS Monterey 12.4 (build 21F79, kernel 21.5.0)",
|
||||
}
|
||||
CPU: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
|
||||
RAM: 8192 MiB
|
||||
RAM: 8.0 GiB
|
||||
*/
|
||||
package sysinfo
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// +build darwin
|
||||
package sysinfo
|
||||
|
||||
import sys "core:sys/unix"
|
||||
@@ -76,6 +75,8 @@ init_os_version :: proc () {
|
||||
os_version.minor = rel.darwin.y
|
||||
os_version.patch = rel.darwin.z
|
||||
|
||||
macos_version = transmute(Version)rel.release.version
|
||||
|
||||
strings.write_string(&b, rel.os_name)
|
||||
if match == .Exact || match == .Nearest {
|
||||
strings.write_rune(&b, ' ')
|
||||
@@ -113,7 +114,7 @@ init_os_version :: proc () {
|
||||
os_version.as_string = strings.to_string(b)
|
||||
}
|
||||
|
||||
@(init)
|
||||
@(init, private)
|
||||
init_ram :: proc() {
|
||||
// Retrieve RAM info using `sysctl`
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// +build freebsd
|
||||
package sysinfo
|
||||
|
||||
import sys "core:sys/unix"
|
||||
@@ -68,7 +67,7 @@ init_os_version :: proc () {
|
||||
}
|
||||
}
|
||||
|
||||
@(init)
|
||||
@(init, private)
|
||||
init_ram :: proc() {
|
||||
// Retrieve RAM info using `sysctl`
|
||||
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// +build linux
|
||||
package sysinfo
|
||||
|
||||
import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
import "core:strings"
|
||||
import "core:strconv"
|
||||
|
||||
import "core:strconv"
|
||||
import "core:strings"
|
||||
import "core:sys/linux"
|
||||
|
||||
@(private)
|
||||
@@ -14,32 +12,37 @@ version_string_buf: [1024]u8
|
||||
@(init, private)
|
||||
init_os_version :: proc () {
|
||||
os_version.platform = .Linux
|
||||
// Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
||||
fd, errno := linux.open("/etc/os-release", {.RDONLY}, {})
|
||||
assert(errno == .NONE, "Failed to read /etc/os-release")
|
||||
defer {
|
||||
cerrno := linux.close(fd)
|
||||
assert(cerrno == .NONE, "Failed to close the file descriptor")
|
||||
}
|
||||
os_release_buf: [2048]u8
|
||||
n, read_errno := linux.read(fd, os_release_buf[:])
|
||||
assert(read_errno == .NONE, "Failed to read data from /etc/os-release")
|
||||
release := string(os_release_buf[:n])
|
||||
// Search the line in the file until we find "PRETTY_NAME="
|
||||
NEEDLE :: "PRETTY_NAME=\""
|
||||
pretty_start := strings.index(release, NEEDLE)
|
||||
|
||||
b := strings.builder_from_bytes(version_string_buf[:])
|
||||
if pretty_start > 0 {
|
||||
for r, i in release[pretty_start + len(NEEDLE):] {
|
||||
if r == '"' {
|
||||
strings.write_string(&b, release[pretty_start + len(NEEDLE):][:i])
|
||||
break
|
||||
} else if r == '\r' || r == '\n' {
|
||||
strings.write_string(&b, "Unknown Linux Distro")
|
||||
break
|
||||
|
||||
// Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
||||
{
|
||||
fd, errno := linux.open("/etc/os-release", {})
|
||||
assert(errno == .NONE, "Failed to read /etc/os-release")
|
||||
defer {
|
||||
cerrno := linux.close(fd)
|
||||
assert(cerrno == .NONE, "Failed to close the file descriptor")
|
||||
}
|
||||
|
||||
os_release_buf: [2048]u8
|
||||
n, read_errno := linux.read(fd, os_release_buf[:])
|
||||
assert(read_errno == .NONE, "Failed to read data from /etc/os-release")
|
||||
release := string(os_release_buf[:n])
|
||||
|
||||
// Search the line in the file until we find "PRETTY_NAME="
|
||||
NEEDLE :: "PRETTY_NAME=\""
|
||||
_, _, post := strings.partition(release, NEEDLE)
|
||||
if len(post) > 0 {
|
||||
end := strings.index_any(post, "\"\n")
|
||||
if end > -1 && post[end] == '"' {
|
||||
strings.write_string(&b, post[:end])
|
||||
}
|
||||
}
|
||||
if strings.builder_len(b) == 0 {
|
||||
strings.write_string(&b, "Unknown Linux Distro")
|
||||
}
|
||||
}
|
||||
|
||||
// Grab kernel info using `uname()` syscall, https://linux.die.net/man/2/uname
|
||||
uts: linux.UTS_Name
|
||||
uname_errno := linux.uname(&uts)
|
||||
@@ -48,31 +51,39 @@ init_os_version :: proc () {
|
||||
strings.write_string(&b, ", ")
|
||||
strings.write_string(&b, string(cstring(&uts.sysname[0])))
|
||||
strings.write_rune(&b, ' ')
|
||||
l := strings.builder_len(b)
|
||||
|
||||
release_i := strings.builder_len(b)
|
||||
strings.write_string(&b, string(cstring(&uts.release[0])))
|
||||
// Parse kernel version, as substrings of the version info in `version_string_buf`
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
version_bits := strings.split_n(strings.to_string(b)[l:], "-", 2, context.temp_allocator)
|
||||
if len(version_bits) > 1 {
|
||||
os_version.version = version_bits[1]
|
||||
}
|
||||
// Parse major, minor, patch from release info
|
||||
triplet := strings.split(version_bits[0], ".", context.temp_allocator)
|
||||
if len(triplet) == 3 {
|
||||
major, major_ok := strconv.parse_int(triplet[0])
|
||||
minor, minor_ok := strconv.parse_int(triplet[1])
|
||||
patch, patch_ok := strconv.parse_int(triplet[2])
|
||||
if major_ok && minor_ok && patch_ok {
|
||||
os_version.major = major
|
||||
os_version.minor = minor
|
||||
os_version.patch = patch
|
||||
release_str := string(b.buf[release_i:])
|
||||
|
||||
os_version.as_string = strings.to_string(b)
|
||||
|
||||
// Parse the Linux version out of the release string
|
||||
{
|
||||
version_num, _, version_suffix := strings.partition(release_str, "-")
|
||||
os_version.version = version_suffix
|
||||
|
||||
i: int
|
||||
for part in strings.split_iterator(&version_num, ".") {
|
||||
defer i += 1
|
||||
|
||||
dst: ^int
|
||||
switch i {
|
||||
case 0: dst = &os_version.major
|
||||
case 1: dst = &os_version.minor
|
||||
case 2: dst = &os_version.patch
|
||||
case: break
|
||||
}
|
||||
|
||||
num, ok := strconv.parse_int(part)
|
||||
if !ok { break }
|
||||
|
||||
dst^ = num
|
||||
}
|
||||
}
|
||||
// Finish the string
|
||||
os_version.as_string = strings.to_string(b)
|
||||
}
|
||||
|
||||
@(init)
|
||||
@(init, private)
|
||||
init_ram :: proc() {
|
||||
// Retrieve RAM info using `sysinfo`
|
||||
sys_info: linux.Sys_Info
|
||||
@@ -84,4 +95,4 @@ init_ram :: proc() {
|
||||
total_swap = int(sys_info.totalswap) * int(sys_info.mem_unit),
|
||||
free_swap = int(sys_info.freeswap) * int(sys_info.mem_unit),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// +build openbsd
|
||||
package sysinfo
|
||||
|
||||
import sys "core:sys/unix"
|
||||
@@ -61,7 +60,7 @@ init_os_version :: proc () {
|
||||
os_version.as_string = strings.to_string(b)
|
||||
}
|
||||
|
||||
@(init)
|
||||
@(init, private)
|
||||
init_ram :: proc() {
|
||||
// Retrieve RAM info using `sysctl`
|
||||
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM64}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// +build windows
|
||||
package sysinfo
|
||||
|
||||
import sys "core:sys/windows"
|
||||
@@ -259,7 +258,7 @@ init_os_version :: proc () {
|
||||
}
|
||||
}
|
||||
|
||||
@(init)
|
||||
@(init, private)
|
||||
init_ram :: proc() {
|
||||
state: sys.MEMORYSTATUSEX
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ os_version: OS_Version
|
||||
ram: RAM
|
||||
gpus: []GPU
|
||||
|
||||
// Only on MacOS, contains the actual MacOS version, while the `os_version` contains the kernel version.
|
||||
macos_version: Version
|
||||
|
||||
OS_Version_Platform :: enum {
|
||||
Unknown,
|
||||
Windows,
|
||||
@@ -19,12 +22,14 @@ OS_Version_Platform :: enum {
|
||||
NetBSD,
|
||||
}
|
||||
|
||||
Version :: struct {
|
||||
major, minor, patch: int,
|
||||
}
|
||||
|
||||
OS_Version :: struct {
|
||||
platform: OS_Version_Platform,
|
||||
|
||||
major: int,
|
||||
minor: int,
|
||||
patch: int,
|
||||
using _: Version,
|
||||
build: [2]int,
|
||||
version: string,
|
||||
|
||||
@@ -42,4 +47,4 @@ GPU :: struct {
|
||||
vendor_name: string,
|
||||
model_name: string,
|
||||
total_ram: int,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
//+build darwin
|
||||
package unix
|
||||
|
||||
import "core:sys/darwin"
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:c"
|
||||
import "core:sys/darwin"
|
||||
|
||||
_ :: darwin
|
||||
|
||||
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
|
||||
mib := mib
|
||||
result_size := i64(size_of(T))
|
||||
sysctl :: proc "contextless" (mib: []i32, val: ^$T) -> (ok: bool) {
|
||||
result_size := c.size_t(size_of(T))
|
||||
res := darwin.syscall_sysctl(
|
||||
raw_data(mib), len(mib),
|
||||
val, &result_size,
|
||||
nil, 0,
|
||||
)
|
||||
return res == 0
|
||||
}
|
||||
|
||||
res := intrinsics.syscall(
|
||||
darwin.unix_offset_syscall(.sysctl),
|
||||
uintptr(raw_data(mib)), uintptr(len(mib)),
|
||||
uintptr(val), uintptr(&result_size),
|
||||
uintptr(0), uintptr(0),
|
||||
sysctlbyname :: proc "contextless" (name: string, val: ^$T) -> (ok: bool) {
|
||||
result_size := c.size_t(size_of(T))
|
||||
res := darwin.syscall_sysctlbyname(
|
||||
name,
|
||||
val, &result_size,
|
||||
nil, 0,
|
||||
)
|
||||
return res == 0
|
||||
}
|
||||
|
||||
@@ -1,21 +1,10 @@
|
||||
//+private
|
||||
//+build darwin
|
||||
package time
|
||||
|
||||
import "core:c"
|
||||
import "core:sys/unix"
|
||||
|
||||
foreign import libc "system:System.framework"
|
||||
foreign libc {
|
||||
@(link_name="sysctlbyname") _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
|
||||
}
|
||||
|
||||
_get_tsc_frequency :: proc "contextless" () -> (u64, bool) {
|
||||
tmp_freq : u64 = 0
|
||||
tmp_size : i64 = size_of(tmp_freq)
|
||||
ret := _sysctlbyname("machdep.tsc.frequency", &tmp_freq, &tmp_size, nil, 0)
|
||||
if ret < 0 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return tmp_freq, true
|
||||
_get_tsc_frequency :: proc "contextless" () -> (freq: u64, ok: bool) {
|
||||
unix.sysctlbyname("machdep.tsc.frequency", &freq) or_return
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
@@ -204,14 +204,27 @@ gb_internal void report_cpu_info() {
|
||||
}
|
||||
|
||||
#elif defined(GB_CPU_ARM)
|
||||
/*
|
||||
TODO(Jeroen): On *nix, perhaps query `/proc/cpuinfo`.
|
||||
*/
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
gb_printf("ARM64\n");
|
||||
#else
|
||||
gb_printf("ARM\n");
|
||||
bool generic = true;
|
||||
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
char cpu_name[128] = {};
|
||||
size_t cpu_name_size = 128;
|
||||
if (sysctlbyname("machdep.cpu.brand_string", &cpu_name, &cpu_name_size, nullptr, 0) == 0) {
|
||||
generic = false;
|
||||
gb_printf("%s\n", (char *)&cpu_name[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (generic) {
|
||||
/*
|
||||
TODO(Jeroen): On *nix, perhaps query `/proc/cpuinfo`.
|
||||
*/
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
gb_printf("ARM64\n");
|
||||
#else
|
||||
gb_printf("ARM\n");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
gb_printf("Unknown\n");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user