github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+incompatible/pkg/sysinfo/numcpu_linux.go (about)

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