mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-28 13:48:49 +08:00
improve sysctl parsing: use native byte order
We can't use unix.Sysctl* for some sysctls, so we're on our own with converting data from C arrays. Don't assume that the byte order is little endian but do the right thing. Moreover, there's a little distinction in the sizes reported by KERN_CPTIME (long[cpustates]) and KERN_CPTIME2 (u_int64_t[cpustates]) so account for that too.
This commit is contained in:
parent
73db061652
commit
16cc7d7d73
@ -4,18 +4,19 @@
|
|||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"github.com/tklauser/go-sysconf"
|
"github.com/tklauser/go-sysconf"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// sys/sched.h
|
// sys/sched.h
|
||||||
cpUser = 0
|
cpUser = 0
|
||||||
@ -51,13 +52,8 @@ func smtEnabled() (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret bool
|
smt := *(*uint32)(unsafe.Pointer(&buf[0]))
|
||||||
br := bytes.NewReader(buf)
|
return smt == 1, nil
|
||||||
if err := binary.Read(br, binary.LittleEndian, &ret); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Times(percpu bool) ([]TimesStat, error) {
|
func Times(percpu bool) ([]TimesStat, error) {
|
||||||
@ -89,7 +85,6 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
|||||||
j *= 2
|
j *= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuTimes := make([]int32, cpuStates)
|
|
||||||
var mib []int32
|
var mib []int32
|
||||||
if percpu {
|
if percpu {
|
||||||
mib = []int32{ctlKern, kernCptime2, int32(j)}
|
mib = []int32{ctlKern, kernCptime2, int32(j)}
|
||||||
@ -101,11 +96,24 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
|||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
br := bytes.NewReader(buf)
|
var cpuTimes [cpuStates]uint64
|
||||||
err = binary.Read(br, binary.LittleEndian, &cpuTimes)
|
if percpu {
|
||||||
if err != nil {
|
// could use unsafe.Slice but it's only for go1.17+
|
||||||
return ret, err
|
var x []uint64
|
||||||
|
x = (*[cpuStates]uint64)(unsafe.Pointer(&buf[0]))[:]
|
||||||
|
for i := range x {
|
||||||
|
cpuTimes[i] = x[i]
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// KERN_CPTIME yields long[CPUSTATES] and `long' is
|
||||||
|
// platform dependent
|
||||||
|
var x []C.long
|
||||||
|
x = (*[cpuStates]C.long)(unsafe.Pointer(&buf[0]))[:]
|
||||||
|
for i := range x {
|
||||||
|
cpuTimes[i] = uint64(x[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c := TimesStat{
|
c := TimesStat{
|
||||||
User: float64(cpuTimes[cpUser]) / ClocksPerSec,
|
User: float64(cpuTimes[cpUser]) / ClocksPerSec,
|
||||||
Nice: float64(cpuTimes[cpNice]) / ClocksPerSec,
|
Nice: float64(cpuTimes[cpNice]) / ClocksPerSec,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user