github.com/olljanat/moby@v1.13.1/pkg/sysinfo/numcpu_linux.go (about)

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