numcpu_linux.go 940 B

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