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
}