numcpu_windows.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package sysinfo // import "github.com/docker/docker/pkg/sysinfo"
  2. import (
  3. "runtime"
  4. "unsafe"
  5. "golang.org/x/sys/windows"
  6. )
  7. var (
  8. kernel32 = windows.NewLazySystemDLL("kernel32.dll")
  9. getCurrentProcess = kernel32.NewProc("GetCurrentProcess")
  10. getProcessAffinityMask = kernel32.NewProc("GetProcessAffinityMask")
  11. )
  12. // Returns bit count of 1, used by NumCPU
  13. func popcnt(x uint64) (n byte) {
  14. x -= (x >> 1) & 0x5555555555555555
  15. x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
  16. x += x >> 4
  17. x &= 0x0f0f0f0f0f0f0f0f
  18. x *= 0x0101010101010101
  19. return byte(x >> 56)
  20. }
  21. func numCPU() int {
  22. // Gets the affinity mask for a process
  23. var mask, sysmask uintptr
  24. currentProcess, _, _ := getCurrentProcess.Call()
  25. ret, _, _ := getProcessAffinityMask.Call(currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
  26. if ret == 0 {
  27. return 0
  28. }
  29. // For every available thread a bit is set in the mask.
  30. ncpu := int(popcnt(uint64(mask)))
  31. return ncpu
  32. }
  33. // NumCPU returns the number of CPUs which are currently online
  34. func NumCPU() int {
  35. if ncpu := numCPU(); ncpu > 0 {
  36. return ncpu
  37. }
  38. return runtime.NumCPU()
  39. }