func Get()

in metric/cpu/metrics_openbsd.go [43:106]


func Get(m *Monitor) (CPUMetrics, error) {

	// see man 2 sysctl
	loadGlobal := [C.CPUSTATES]C.long{
		C.CP_USER,
		C.CP_NICE,
		C.CP_SYS,
		C.CP_INTR,
		C.CP_IDLE,
	}

	// first, fetch global CPU data
	err := sysctlGetCPUTimes(0, 0, &loadGlobal)
	if err != nil {
		return CPUMetrics{}, err
	}
	self := CPU{}
	self.User = opt.UintWith(loadGlobal[0])
	self.Nice = opt.UintWith(loadGlobal[1])
	self.Sys = opt.UintWith(loadGlobal[2])
	self.Irq = opt.UintWith(loadGlobal[3])
	self.Idle = opt.UintWith(loadGlobal[4])
	// Get count of available CPUs
	ncpuMIB := [2]int32{C.CTL_HW, C.HW_NCPU}
	callSize := uintptr(0)
	var ncpu int
	// The first call nulls out the retun pointer, so we instead fetch the expected size of expected return value.
	_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&ncpuMIB[0])), 2, 0, uintptr(unsafe.Pointer(&callSize)), 0, 0)

	if errno != 0 || callSize == 0 {
		return CPUMetrics{}, errno
	}

	// Populate the cpu count
	_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&ncpuMIB[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&callSize)), 0, 0)

	if errno != 0 || callSize == 0 {
		return CPUMetrics{}, errno
	}

	loadPerCPU := [C.CPUSTATES]C.long{
		C.CP_USER,
		C.CP_NICE,
		C.CP_SYS,
		C.CP_INTR,
		C.CP_IDLE,
	}

	perCPU := make([]CPU, ncpu)

	// iterate over metrics for each CPU
	for i := 0; i < ncpu; i++ {
		sysctlGetCPUTimes(ncpu, i, &loadPerCPU)
		perCPU[i].User = opt.UintWith(loadGlobal[0])
		perCPU[i].Nice = opt.UintWith(loadGlobal[1])
		perCPU[i].Sys = opt.UintWith(loadGlobal[2])
		perCPU[i].Irq = opt.UintWith(loadGlobal[3])
		perCPU[i].Idle = opt.UintWith(loadGlobal[4])
	}

	metrics := CPUMetrics{totals: self, list: perCPU}

	return metrics, nil
}