summaryrefslogtreecommitdiff
path: root/pkg/sysinfo/numcpu_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sysinfo/numcpu_linux.go')
-rw-r--r--pkg/sysinfo/numcpu_linux.go44
1 files changed, 44 insertions, 0 deletions
diff --git a/pkg/sysinfo/numcpu_linux.go b/pkg/sysinfo/numcpu_linux.go
new file mode 100644
index 000000000..f1d2d9db3
--- /dev/null
+++ b/pkg/sysinfo/numcpu_linux.go
@@ -0,0 +1,44 @@
+// +build linux
+
+package sysinfo
+
+import (
+ "runtime"
+ "unsafe"
+
+ "golang.org/x/sys/unix"
+)
+
+// numCPU queries the system for the count of threads available
+// for use to this process.
+//
+// Issues two syscalls.
+// Returns 0 on errors. Use |runtime.NumCPU| in that case.
+func numCPU() int {
+ // Gets the affinity mask for a process: The very one invoking this function.
+ pid, _, _ := unix.RawSyscall(unix.SYS_GETPID, 0, 0, 0)
+
+ var mask [1024 / 64]uintptr
+ _, _, err := unix.RawSyscall(unix.SYS_SCHED_GETAFFINITY, pid, uintptr(len(mask)*8), uintptr(unsafe.Pointer(&mask[0])))
+ if err != 0 {
+ return 0
+ }
+
+ // For every available thread a bit is set in the mask.
+ ncpu := 0
+ for _, e := range mask {
+ if e == 0 {
+ continue
+ }
+ ncpu += int(popcnt(uint64(e)))
+ }
+ return ncpu
+}
+
+// NumCPU returns the number of CPUs which are currently online
+func NumCPU() int {
+ if ncpu := numCPU(); ncpu > 0 {
+ return ncpu
+ }
+ return runtime.NumCPU()
+}