github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/pkg/sysinfo/numcpu_windows.go (about)

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