diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index 353991e..92a8bd7 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -11,6 +11,7 @@ import ( "runtime" "strconv" "strings" + "syscall" "github.com/shirou/gopsutil/internal/common" "golang.org/x/sys/unix" @@ -29,6 +30,9 @@ var ( // sys/sysctl.h const ( CTLKern = 1 // "high kernel": proc, limits + CTLHw = 6 // CTL_HW + SMT = 24 // HW_SMT + NCpuOnline = 25 // HW_NCPUONLINE KernCptime = 40 // KERN_CPTIME KernCptime2 = 71 // KERN_CPTIME2 ) @@ -68,6 +72,22 @@ func init() { }() } +func smt() (bool, error) { + mib := []int32{CTLHw, SMT} + buf, _, err := common.CallSyscall(mib) + if err != nil { + return false, err + } + + var ret bool + br := bytes.NewReader(buf) + if err := binary.Read(br, binary.LittleEndian, &ret); err != nil { + return false, err + } + + return ret, nil +} + func Times(percpu bool) ([]TimesStat, error) { return TimesWithContext(context.Background(), percpu) } @@ -82,13 +102,27 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { ncpu = 1 } + smt, err := smt() + if err == syscall.EOPNOTSUPP { + // if hw.smt is not applicable for this platform (e.g. i386), + // pretend it's enabled + smt = true + } else if err != nil { + return nil, err + } + for i := 0; i < ncpu; i++ { - var cpuTimes = make([]int64, CPUStates) + j := i + if !smt { + j *= 2 + } + + var cpuTimes = make([]int32, CPUStates) var mib []int32 if percpu { - mib = []int32{CTLKern, KernCptime} + mib = []int32{CTLKern, KernCptime2, int32(j)} } else { - mib = []int32{CTLKern, KernCptime2, int32(i)} + mib = []int32{CTLKern, KernCptime} } buf, _, err := common.CallSyscall(mib) if err != nil { @@ -107,10 +141,10 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec, Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec, } - if !percpu { - c.CPU = "cpu-total" + if percpu { + c.CPU = fmt.Sprintf("cpu%d", j) } else { - c.CPU = fmt.Sprintf("cpu%d", i) + c.CPU = "cpu-total" } ret = append(ret, c) } @@ -135,10 +169,19 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { } c.Mhz = float64(u32) - if u32, err = unix.SysctlUint32("hw.ncpuonline"); err != nil { + mib := []int32{CTLHw, NCpuOnline} + buf, _, err := common.CallSyscall(mib) + if err != nil { return nil, err } - c.Cores = int32(u32) + + var ncpu int32 + br := bytes.NewReader(buf) + err = binary.Read(br, binary.LittleEndian, &ncpu) + if err != nil { + return nil, err + } + c.Cores = ncpu if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { return nil, err