mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-01 02:42:05 +00:00
impr: std/cpuinfo: use documented impl ; support JS (#23911)
Currently `cpuinfo.countProcessor` uses hard-coded `HW_AVAILCPU=25` for both MacOS and BSD; However, [There is no HW_AVAILCPU on FreeBSD, NetBSD, and OpenBSD]( https://bugs.webkit.org/show_bug.cgi?id=132542) Also, `HW_AVAILCPU` is undocmented in MacOS, while `sysctlbyname("hw.logicalcpu",...)` is documented and used by many other languages' implementations, like [Haskell](https://gitlab.haskell.org/ghc/ghc/-/blob/master/rts/posix/OSThreads.c?ref_type=heads#L376) --- This PR: - use `importc` value instead of hard-coded values for `HW_*` macros. - use "hw.logicialcpu" over undocumented HW_AVAILCPU. - reduce 2 elements of `mib` array when calling `sysctl` as they're no use.
This commit is contained in:
@@ -15,75 +15,96 @@ runnableExamples:
|
||||
|
||||
include "system/inclrtl"
|
||||
|
||||
when defined(posix) and not (defined(macosx) or defined(bsd)):
|
||||
import std/posix
|
||||
when defined(js):
|
||||
import std/jsffi
|
||||
proc countProcessorsImpl(): int =
|
||||
when defined(nodejs):
|
||||
let jsOs = require("os")
|
||||
let jsObj = jsOs.cpus().length
|
||||
else:
|
||||
# `navigator.hardwareConcurrency`
|
||||
# works on browser as well as deno.
|
||||
let navigator{.importcpp.}: JsObject
|
||||
let jsObj = navigator.hardwareConcurrency
|
||||
result = jsObj.to int
|
||||
else:
|
||||
when defined(posix) and not (defined(macosx) or defined(bsd)):
|
||||
import std/posix
|
||||
|
||||
when defined(windows):
|
||||
import std/private/win_getsysteminfo
|
||||
when defined(windows):
|
||||
import std/private/win_getsysteminfo
|
||||
|
||||
when defined(freebsd) or defined(macosx):
|
||||
{.emit: "#include <sys/types.h>".}
|
||||
when defined(freebsd) or defined(macosx):
|
||||
{.emit: "#include <sys/types.h>".}
|
||||
|
||||
when defined(openbsd) or defined(netbsd):
|
||||
{.emit: "#include <sys/param.h>".}
|
||||
when defined(openbsd) or defined(netbsd):
|
||||
{.emit: "#include <sys/param.h>".}
|
||||
|
||||
when defined(macosx) or defined(bsd):
|
||||
# we HAVE to emit param.h before sysctl.h so we cannot use .header here
|
||||
# either. The amount of archaic bullshit in Poonix based OSes is just insane.
|
||||
{.emit: "#include <sys/sysctl.h>".}
|
||||
const
|
||||
CTL_HW = 6
|
||||
HW_AVAILCPU = 25
|
||||
HW_NCPU = 3
|
||||
proc sysctl(x: ptr array[0..3, cint], y: cint, z: pointer,
|
||||
a: var csize_t, b: pointer, c: csize_t): cint {.
|
||||
importc: "sysctl", nodecl.}
|
||||
when defined(macosx) or defined(bsd):
|
||||
# we HAVE to emit param.h before sysctl.h so we cannot use .header here
|
||||
# either. The amount of archaic bullshit in Poonix based OSes is just insane.
|
||||
{.emit: "#include <sys/sysctl.h>".}
|
||||
{.push nodecl.}
|
||||
when defined(macosx):
|
||||
proc sysctlbyname(name: cstring,
|
||||
oldp: pointer, oldlenp: var csize_t,
|
||||
newp: pointer, newlen: csize_t): cint {.importc.}
|
||||
let
|
||||
CTL_HW{.importc.}: cint
|
||||
HW_NCPU{.importc.}: cint
|
||||
proc sysctl[I: static[int]](name: var array[I, cint], namelen: cuint,
|
||||
oldp: pointer, oldlenp: var csize_t,
|
||||
newp: pointer, newlen: csize_t): cint {.importc.}
|
||||
{.pop.}
|
||||
|
||||
when defined(genode):
|
||||
import genode/env
|
||||
when defined(genode):
|
||||
import genode/env
|
||||
|
||||
proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
|
||||
importcpp: "@->cpu().affinity_space().total()".}
|
||||
proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
|
||||
importcpp: "@->cpu().affinity_space().total()".}
|
||||
|
||||
when defined(haiku):
|
||||
type
|
||||
SystemInfo {.importc: "system_info", header: "<OS.h>".} = object
|
||||
cpuCount {.importc: "cpu_count".}: uint32
|
||||
|
||||
proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info",
|
||||
header: "<OS.h>".}
|
||||
|
||||
proc countProcessorsImpl(): int {.inline.} =
|
||||
when defined(windows):
|
||||
var
|
||||
si: SystemInfo
|
||||
getSystemInfo(addr si)
|
||||
result = int(si.dwNumberOfProcessors)
|
||||
elif defined(macosx) or defined(bsd):
|
||||
let dest = addr result
|
||||
var len = sizeof(result).csize_t
|
||||
when defined(macosx):
|
||||
# alias of "hw.activecpu"
|
||||
if sysctlbyname("hw.logicalcpu", dest, len, nil, 0) == 0:
|
||||
return
|
||||
var mib = [CTL_HW, HW_NCPU]
|
||||
if sysctl(mib, 2, dest, len, nil, 0) == 0:
|
||||
return
|
||||
elif defined(hpux):
|
||||
result = mpctl(MPC_GETNUMSPUS, nil, nil)
|
||||
elif defined(irix):
|
||||
var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
|
||||
result = sysconf(SC_NPROC_ONLN)
|
||||
elif defined(genode):
|
||||
result = runtimeEnv.affinitySpaceTotal().int
|
||||
elif defined(haiku):
|
||||
var sysinfo: SystemInfo
|
||||
if getSystemInfo(addr sysinfo) == 0:
|
||||
result = sysinfo.cpuCount.int
|
||||
else:
|
||||
result = sysconf(SC_NPROCESSORS_ONLN)
|
||||
if result < 0: result = 0
|
||||
|
||||
when defined(haiku):
|
||||
type
|
||||
SystemInfo {.importc: "system_info", header: "<OS.h>".} = object
|
||||
cpuCount {.importc: "cpu_count".}: uint32
|
||||
|
||||
proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info",
|
||||
header: "<OS.h>".}
|
||||
|
||||
proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
|
||||
## Returns the number of the processors/cores the machine has.
|
||||
## Returns 0 if it cannot be detected.
|
||||
when defined(windows):
|
||||
var
|
||||
si: SystemInfo
|
||||
getSystemInfo(addr si)
|
||||
result = int(si.dwNumberOfProcessors)
|
||||
elif defined(macosx) or defined(bsd):
|
||||
var
|
||||
mib: array[0..3, cint]
|
||||
numCPU: int
|
||||
mib[0] = CTL_HW
|
||||
mib[1] = HW_AVAILCPU
|
||||
var len = sizeof(numCPU).csize_t
|
||||
discard sysctl(addr(mib), 2, addr(numCPU), len, nil, 0)
|
||||
if numCPU < 1:
|
||||
mib[1] = HW_NCPU
|
||||
discard sysctl(addr(mib), 2, addr(numCPU), len, nil, 0)
|
||||
result = numCPU
|
||||
elif defined(hpux):
|
||||
result = mpctl(MPC_GETNUMSPUS, nil, nil)
|
||||
elif defined(irix):
|
||||
var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
|
||||
result = sysconf(SC_NPROC_ONLN)
|
||||
elif defined(genode):
|
||||
result = runtimeEnv.affinitySpaceTotal().int
|
||||
elif defined(haiku):
|
||||
var sysinfo: SystemInfo
|
||||
if getSystemInfo(addr sysinfo) == 0:
|
||||
result = sysinfo.cpuCount.int
|
||||
else:
|
||||
result = sysconf(SC_NPROCESSORS_ONLN)
|
||||
if result <= 0: result = 0
|
||||
countProcessorsImpl()
|
||||
|
||||
Reference in New Issue
Block a user