Skip to content

Commit cf50d7e

Browse files
authored
implements std/cpuinfo (#1538)
1 parent 90af2f4 commit cf50d7e

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

lib/std/cpuinfo.nim

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#
2+
#
3+
# Nim's Runtime Library
4+
# (c) Copyright 2015 Andreas Rumpf
5+
#
6+
# See the file "copying.txt", included in this
7+
# distribution, for details about the copyright.
8+
#
9+
10+
## This module implements a proc to determine the number of CPUs / cores.
11+
12+
# runnableExamples:
13+
# import std/assertions
14+
# asssert countProcessors() > 0
15+
16+
17+
when defined(js):
18+
import std/jsffi
19+
proc countProcessorsImpl(): int =
20+
when defined(nodejs):
21+
let jsOs = require("os")
22+
let jsObj = jsOs.cpus().length
23+
else:
24+
# `navigator.hardwareConcurrency`
25+
# works on browser as well as deno.
26+
let navigator{.importcpp.}: JsObject
27+
let jsObj = navigator.hardwareConcurrency
28+
result = jsObj.to int
29+
else:
30+
when defined(posix) and not (defined(macosx) or defined(bsd)):
31+
import posix/posix
32+
33+
when defined(windows):
34+
type
35+
SystemInfo = object
36+
u1: uint32
37+
dwPageSize: uint32
38+
lpMinimumApplicationAddress: pointer
39+
lpMaximumApplicationAddress: pointer
40+
dwActiveProcessorMask: ptr uint32
41+
dwNumberOfProcessors: uint32
42+
dwProcessorType: uint32
43+
dwAllocationGranularity: uint32
44+
wProcessorLevel: uint16
45+
wProcessorRevision: uint16
46+
47+
proc getSystemInfo(lpSystemInfo: ptr SystemInfo) {.stdcall,
48+
dynlib: "kernel32", importc: "GetSystemInfo".}
49+
50+
51+
when defined(freebsd) or defined(macosx):
52+
{.emit: "#include <sys/types.h>".}
53+
54+
when defined(openbsd) or defined(netbsd):
55+
{.emit: "#include <sys/param.h>".}
56+
57+
when defined(macosx) or defined(bsd):
58+
# we HAVE to emit param.h before sysctl.h so we cannot use .header here
59+
# either. The amount of archaic bullshit in Poonix based OSes is just insane.
60+
{.emit: "#include <sys/sysctl.h>".}
61+
{.push nodecl.}
62+
when defined(macosx):
63+
proc sysctlbyname(name: cstring,
64+
oldp: pointer, oldlenp: var csize_t,
65+
newp: pointer, newlen: csize_t): cint {.importc.}
66+
let
67+
CTL_HW{.importc.}: cint
68+
HW_NCPU{.importc.}: cint
69+
proc sysctl[I](name: var array[I, cint], namelen: cuint,
70+
oldp: pointer, oldlenp: var csize_t,
71+
newp: pointer, newlen: csize_t): cint {.importc.}
72+
{.pop.}
73+
74+
when defined(genode):
75+
import genode/env
76+
77+
proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
78+
importcpp: "@->cpu().affinity_space().total()".}
79+
80+
when defined(haiku):
81+
type
82+
SystemInfo {.importc: "system_info", header: "<OS.h>".} = object
83+
cpuCount {.importc: "cpu_count".}: uint32
84+
85+
proc getSystemInfo(info: ptr SystemInfo): int32 {.importc: "get_system_info",
86+
header: "<OS.h>".}
87+
88+
proc countProcessorsImpl(): int {.inline.} =
89+
when defined(windows):
90+
var
91+
si: SystemInfo = default(SystemInfo)
92+
getSystemInfo(addr si)
93+
result = int(si.dwNumberOfProcessors)
94+
elif defined(macosx) or defined(bsd):
95+
result = 0
96+
let dest = addr result
97+
var len = sizeof(result).csize_t
98+
when defined(macosx):
99+
# alias of "hw.activecpu"
100+
if sysctlbyname("hw.logicalcpu", dest, len, nil, 0) == 0:
101+
return
102+
var mib = [CTL_HW, HW_NCPU]
103+
if sysctl(mib, 2, dest, len, nil, 0) == 0:
104+
return
105+
elif defined(hpux):
106+
result = mpctl(MPC_GETNUMSPUS, nil, nil)
107+
elif defined(irix):
108+
var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
109+
result = sysconf(SC_NPROC_ONLN)
110+
elif defined(genode):
111+
result = runtimeEnv.affinitySpaceTotal().int
112+
elif defined(haiku):
113+
var sysinfo: SystemInfo
114+
if getSystemInfo(addr sysinfo) == 0:
115+
result = sysinfo.cpuCount.int
116+
else:
117+
result = 0
118+
else:
119+
result = sysconf(SC_NPROCESSORS_ONLN)
120+
if result < 0: result = 0
121+
122+
123+
124+
proc countProcessors*(): int =
125+
## Returns the number of the processors/cores the machine has.
126+
## Returns 0 if it cannot be detected.
127+
countProcessorsImpl()

lib/std/posix/posix.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,6 @@ when defined(posix):
141141
DT_LNK* = 10'u8 ## Symbolic link.
142142
DT_SOCK* = 12'u8 ## UNIX domain socket.
143143
DT_WHT* = 14'u8
144+
145+
146+
proc sysconf*(a1: cint): int {.importc, header: "<unistd.h>".}

tests/nimony/stdlib/tcpuinfo.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import std/cpuinfo
2+
3+
discard countProcessors()

0 commit comments

Comments
 (0)