Skip to content

Commit d33b2df

Browse files
authored
Merge pull request #1244 from omar-polo/master
fix cpu_openbsd.go once and for all
2 parents 2fa880a + 73f9c8d commit d33b2df

File tree

3 files changed

+77
-99
lines changed

3 files changed

+77
-99
lines changed

cpu/cpu_openbsd.go

Lines changed: 57 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -4,141 +4,99 @@
44
package cpu
55

66
import (
7-
"bytes"
87
"context"
9-
"encoding/binary"
108
"fmt"
119
"runtime"
12-
"strconv"
13-
"strings"
14-
"syscall"
10+
"unsafe"
1511

1612
"github.com/shirou/gopsutil/v3/internal/common"
1713
"github.com/tklauser/go-sysconf"
1814
"golang.org/x/sys/unix"
1915
)
2016

21-
// sys/sched.h
22-
var (
23-
CPUser = 0
24-
cpNice = 1
25-
cpSys = 2
26-
cpIntr = 3
27-
cpIdle = 4
28-
cpUStates = 5
29-
)
30-
31-
// sys/sysctl.h
3217
const (
33-
ctlKern = 1 // "high kernel": proc, limits
34-
ctlHw = 6 // CTL_HW
35-
sMT = 24 // HW_sMT
36-
kernCptime = 40 // KERN_CPTIME
37-
kernCptime2 = 71 // KERN_CPTIME2
18+
// sys/sched.h
19+
cpuOnline = 0x0001 // CPUSTATS_ONLINE
20+
21+
// sys/sysctl.h
22+
ctlKern = 1 // "high kernel": proc, limits
23+
ctlHw = 6 // CTL_HW
24+
smt = 24 // HW_SMT
25+
kernCpTime = 40 // KERN_CPTIME
26+
kernCPUStats = 85 // KERN_CPUSTATS
3827
)
3928

4029
var ClocksPerSec = float64(128)
4130

31+
type cpuStats struct {
32+
// cs_time[CPUSTATES]
33+
User uint64
34+
Nice uint64
35+
Sys uint64
36+
Spin uint64
37+
Intr uint64
38+
Idle uint64
39+
40+
// cs_flags
41+
Flags uint64
42+
}
43+
4244
func init() {
4345
clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK)
4446
// ignore errors
4547
if err == nil {
4648
ClocksPerSec = float64(clkTck)
4749
}
48-
49-
func() {
50-
v, err := unix.Sysctl("kern.osrelease") // can't reuse host.PlatformInformation because of circular import
51-
if err != nil {
52-
return
53-
}
54-
v = strings.ToLower(v)
55-
version, err := strconv.ParseFloat(v, 64)
56-
if err != nil {
57-
return
58-
}
59-
if version >= 6.4 {
60-
cpIntr = 4
61-
cpIdle = 5
62-
cpUStates = 6
63-
}
64-
}()
65-
}
66-
67-
func smt() (bool, error) {
68-
mib := []int32{ctlHw, sMT}
69-
buf, _, err := common.CallSyscall(mib)
70-
if err != nil {
71-
return false, err
72-
}
73-
74-
var ret bool
75-
br := bytes.NewReader(buf)
76-
if err := binary.Read(br, binary.LittleEndian, &ret); err != nil {
77-
return false, err
78-
}
79-
80-
return ret, nil
8150
}
8251

8352
func Times(percpu bool) ([]TimesStat, error) {
8453
return TimesWithContext(context.Background(), percpu)
8554
}
8655

87-
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
88-
var ret []TimesStat
89-
90-
var ncpu int
91-
if percpu {
92-
ncpu, _ = Counts(true)
93-
} else {
94-
ncpu = 1
56+
func TimesWithContext(ctx context.Context, percpu bool) (ret []TimesStat, err error) {
57+
if !percpu {
58+
mib := []int32{ctlKern, kernCpTime}
59+
buf, _, err := common.CallSyscall(mib)
60+
if err != nil {
61+
return ret, err
62+
}
63+
times := (*cpuTimes)(unsafe.Pointer(&buf[0]))
64+
stat := TimesStat{
65+
CPU: "cpu-total",
66+
User: float64(times.User) / ClocksPerSec,
67+
Nice: float64(times.Nice) / ClocksPerSec,
68+
System: float64(times.Sys) / ClocksPerSec,
69+
Idle: float64(times.Idle) / ClocksPerSec,
70+
Irq: float64(times.Intr) / ClocksPerSec,
71+
}
72+
return []TimesStat{stat}, nil
9573
}
9674

97-
smt, err := smt()
98-
if err == syscall.EOPNOTSUPP {
99-
// if hw.smt is not applicable for this platform (e.g. i386),
100-
// pretend it's enabled
101-
smt = true
102-
} else if err != nil {
103-
return nil, err
75+
ncpu, err := unix.SysctlUint32("hw.ncpu")
76+
if err != nil {
77+
return
10478
}
10579

106-
for i := 0; i < ncpu; i++ {
107-
j := i
108-
if !smt {
109-
j *= 2
110-
}
111-
112-
cpuTimes := make([]int32, cpUStates)
113-
var mib []int32
114-
if percpu {
115-
mib = []int32{ctlKern, kernCptime2, int32(j)}
116-
} else {
117-
mib = []int32{ctlKern, kernCptime}
118-
}
80+
var i uint32
81+
for i = 0; i < ncpu; i++ {
82+
mib := []int32{ctlKern, kernCPUStats, int32(i)}
11983
buf, _, err := common.CallSyscall(mib)
12084
if err != nil {
12185
return ret, err
12286
}
12387

124-
br := bytes.NewReader(buf)
125-
err = binary.Read(br, binary.LittleEndian, &cpuTimes)
126-
if err != nil {
127-
return ret, err
128-
}
129-
c := TimesStat{
130-
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
131-
Nice: float64(cpuTimes[cpNice]) / ClocksPerSec,
132-
System: float64(cpuTimes[cpSys]) / ClocksPerSec,
133-
Idle: float64(cpuTimes[cpIdle]) / ClocksPerSec,
134-
Irq: float64(cpuTimes[cpIntr]) / ClocksPerSec,
135-
}
136-
if percpu {
137-
c.CPU = fmt.Sprintf("cpu%d", j)
138-
} else {
139-
c.CPU = "cpu-total"
88+
stats := (*cpuStats)(unsafe.Pointer(&buf[0]))
89+
if (stats.Flags & cpuOnline) == 0 {
90+
continue
14091
}
141-
ret = append(ret, c)
92+
ret = append(ret, TimesStat{
93+
CPU: fmt.Sprintf("cpu%d", i),
94+
User: float64(stats.User) / ClocksPerSec,
95+
Nice: float64(stats.Nice) / ClocksPerSec,
96+
System: float64(stats.Sys) / ClocksPerSec,
97+
Idle: float64(stats.Idle) / ClocksPerSec,
98+
Irq: float64(stats.Intr) / ClocksPerSec,
99+
})
142100
}
143101

144102
return ret, nil

cpu/cpu_openbsd_386.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package cpu
2+
3+
type cpuTimes struct {
4+
User uint32
5+
Nice uint32
6+
Sys uint32
7+
Spin uint32
8+
Intr uint32
9+
Idle uint32
10+
}

cpu/cpu_openbsd_amd64.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package cpu
2+
3+
type cpuTimes struct {
4+
User uint64
5+
Nice uint64
6+
Sys uint64
7+
Spin uint64
8+
Intr uint64
9+
Idle uint64
10+
}

0 commit comments

Comments
 (0)