github.com/rhatdan/docker@v0.7.7-0.20180119204836-47a0dcbcd20a/pkg/sysinfo/numcpu_linux.go (about)

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