mirror of
https://github.com/status-im/consul.git
synced 2025-01-11 22:34:55 +00:00
95c027a3ea
https://github.com/shirou/gopsutil/pull/895 is merged and fixes our problem. Time to update. Since there is no new version just yet, updating to the sha.
196 lines
3.7 KiB
Go
196 lines
3.7 KiB
Go
// +build openbsd
|
|
|
|
package cpu
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"os/exec"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/shirou/gopsutil/internal/common"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// sys/sched.h
|
|
var (
|
|
CPUser = 0
|
|
CPNice = 1
|
|
CPSys = 2
|
|
CPIntr = 3
|
|
CPIdle = 4
|
|
CPUStates = 5
|
|
)
|
|
|
|
// 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
|
|
)
|
|
|
|
var ClocksPerSec = float64(128)
|
|
|
|
func init() {
|
|
func() {
|
|
getconf, err := exec.LookPath("getconf")
|
|
if err != nil {
|
|
return
|
|
}
|
|
out, err := invoke.Command(getconf, "CLK_TCK")
|
|
// ignore errors
|
|
if err == nil {
|
|
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
|
|
if err == nil {
|
|
ClocksPerSec = float64(i)
|
|
}
|
|
}
|
|
}()
|
|
func() {
|
|
v, err := unix.Sysctl("kern.osrelease") // can't reuse host.PlatformInformation because of circular import
|
|
if err != nil {
|
|
return
|
|
}
|
|
v = strings.ToLower(v)
|
|
version, err := strconv.ParseFloat(v, 64)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if version >= 6.4 {
|
|
CPIntr = 4
|
|
CPIdle = 5
|
|
CPUStates = 6
|
|
}
|
|
}()
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
|
var ret []TimesStat
|
|
|
|
var ncpu int
|
|
if percpu {
|
|
ncpu, _ = Counts(true)
|
|
} else {
|
|
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++ {
|
|
j := i
|
|
if !smt {
|
|
j *= 2
|
|
}
|
|
|
|
var cpuTimes = make([]int32, CPUStates)
|
|
var mib []int32
|
|
if percpu {
|
|
mib = []int32{CTLKern, KernCptime2, int32(j)}
|
|
} else {
|
|
mib = []int32{CTLKern, KernCptime}
|
|
}
|
|
buf, _, err := common.CallSyscall(mib)
|
|
if err != nil {
|
|
return ret, err
|
|
}
|
|
|
|
br := bytes.NewReader(buf)
|
|
err = binary.Read(br, binary.LittleEndian, &cpuTimes)
|
|
if err != nil {
|
|
return ret, err
|
|
}
|
|
c := TimesStat{
|
|
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
|
|
Nice: float64(cpuTimes[CPNice]) / ClocksPerSec,
|
|
System: float64(cpuTimes[CPSys]) / ClocksPerSec,
|
|
Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec,
|
|
Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec,
|
|
}
|
|
if percpu {
|
|
c.CPU = fmt.Sprintf("cpu%d", j)
|
|
} else {
|
|
c.CPU = "cpu-total"
|
|
}
|
|
ret = append(ret, c)
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
// Returns only one (minimal) CPUInfoStat on OpenBSD
|
|
func Info() ([]InfoStat, error) {
|
|
return InfoWithContext(context.Background())
|
|
}
|
|
|
|
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
|
var ret []InfoStat
|
|
var err error
|
|
|
|
c := InfoStat{}
|
|
|
|
var u32 uint32
|
|
if u32, err = unix.SysctlUint32("hw.cpuspeed"); err != nil {
|
|
return nil, err
|
|
}
|
|
c.Mhz = float64(u32)
|
|
|
|
mib := []int32{CTLHw, NCpuOnline}
|
|
buf, _, err := common.CallSyscall(mib)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
return append(ret, c), nil
|
|
}
|
|
|
|
func CountsWithContext(ctx context.Context, logical bool) (int, error) {
|
|
return runtime.NumCPU(), nil
|
|
}
|