numcpu_linux.go 960 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // +build linux
  2. package sysinfo
  3. import (
  4. "runtime"
  5. "syscall"
  6. "unsafe"
  7. "golang.org/x/sys/unix"
  8. )
  9. // numCPU queries the system for the count of threads available
  10. // for use to this process.
  11. //
  12. // Issues two syscalls.
  13. // Returns 0 on errors. Use |runtime.NumCPU| in that case.
  14. func numCPU() int {
  15. // Gets the affinity mask for a process: The very one invoking this function.
  16. pid, _, _ := syscall.RawSyscall(unix.SYS_GETPID, 0, 0, 0)
  17. var mask [1024 / 64]uintptr
  18. _, _, err := syscall.RawSyscall(unix.SYS_SCHED_GETAFFINITY, pid, uintptr(len(mask)*8), uintptr(unsafe.Pointer(&mask[0])))
  19. if err != 0 {
  20. return 0
  21. }
  22. // For every available thread a bit is set in the mask.
  23. ncpu := 0
  24. for _, e := range mask {
  25. if e == 0 {
  26. continue
  27. }
  28. ncpu += int(popcnt(uint64(e)))
  29. }
  30. return ncpu
  31. }
  32. // NumCPU returns the number of CPUs which are currently online
  33. func NumCPU() int {
  34. if ncpu := numCPU(); ncpu > 0 {
  35. return ncpu
  36. }
  37. return runtime.NumCPU()
  38. }