From 73f9c8dfd5862a54baeb00c3221dc6bc44fce3fd Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Thu, 24 Feb 2022 14:59:20 +0100 Subject: [PATCH] avoid cgo for cpu_openbsd Even thought OpenBSD often breaks the ABI compatibility and doesn't make *any* promise of "stability", this project aims to be "pure go" so avoid doing inter-op at the cost of artificially reducing the number of supported architectures down to amd64 and i386. To add support for another architecture (e.g. arm), add another file cpu_openbsd_${arch}.go like done for 386 and amd64. The fields are declared as `long' in C, so pick the appropriate size when declaring the struct. --- cpu/cpu_openbsd.go | 69 +++++++++++++++++++--------------------- cpu/cpu_openbsd_386.go | 10 ++++++ cpu/cpu_openbsd_amd64.go | 10 ++++++ 3 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 cpu/cpu_openbsd_386.go create mode 100644 cpu/cpu_openbsd_amd64.go diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index 60d02b8a..fe332903 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -14,17 +14,8 @@ import ( "golang.org/x/sys/unix" ) -import "C" - const ( // sys/sched.h - cpUser = 0 - cpNice = 1 - cpSys = 2 - cpSpin = 3 - cpIntr = 4 - cpIdle = 5 - cpuStates = 6 cpuOnline = 0x0001 // CPUSTATS_ONLINE // sys/sysctl.h @@ -37,6 +28,19 @@ const ( var ClocksPerSec = float64(128) +type cpuStats struct { + // cs_time[CPUSTATES] + User uint64 + Nice uint64 + Sys uint64 + Spin uint64 + Intr uint64 + Idle uint64 + + // cs_flags + Flags uint64 +} + func init() { clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors @@ -49,17 +53,6 @@ func Times(percpu bool) ([]TimesStat, error) { return TimesWithContext(context.Background(), percpu) } -func cpsToTS(cpuTimes []uint64, name string) TimesStat { - return TimesStat{ - CPU: name, - 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, - } -} - func TimesWithContext(ctx context.Context, percpu bool) (ret []TimesStat, err error) { if !percpu { mib := []int32{ctlKern, kernCpTime} @@ -67,15 +60,16 @@ func TimesWithContext(ctx context.Context, percpu bool) (ret []TimesStat, err er if err != nil { return ret, err } - var x []C.long - // could use unsafe.Slice but it's only for go1.17+ - x = (*[cpuStates]C.long)(unsafe.Pointer(&buf[0]))[:] - cpuTimes := [cpuStates]uint64{} - for i := range x { - cpuTimes[i] = uint64(x[i]) + times := (*cpuTimes)(unsafe.Pointer(&buf[0])) + stat := TimesStat{ + CPU: "cpu-total", + User: float64(times.User) / ClocksPerSec, + Nice: float64(times.Nice) / ClocksPerSec, + System: float64(times.Sys) / ClocksPerSec, + Idle: float64(times.Idle) / ClocksPerSec, + Irq: float64(times.Intr) / ClocksPerSec, } - c := cpsToTS(cpuTimes[:], "cpu-total") - return []TimesStat{c}, nil + return []TimesStat{stat}, nil } ncpu, err := unix.SysctlUint32("hw.ncpu") @@ -91,17 +85,18 @@ func TimesWithContext(ctx context.Context, percpu bool) (ret []TimesStat, err er return ret, err } - data := unsafe.Pointer(&buf[0]) - fptr := unsafe.Pointer(uintptr(data) + uintptr(8*cpuStates)) - flags := *(*uint64)(fptr) - if (flags & cpuOnline) == 0 { + stats := (*cpuStats)(unsafe.Pointer(&buf[0])) + if (stats.Flags & cpuOnline) == 0 { continue } - - var x []uint64 - x = (*[cpuStates]uint64)(data)[:] - c := cpsToTS(x, fmt.Sprintf("cpu%d", i)) - ret = append(ret, c) + ret = append(ret, TimesStat{ + CPU: fmt.Sprintf("cpu%d", i), + User: float64(stats.User) / ClocksPerSec, + Nice: float64(stats.Nice) / ClocksPerSec, + System: float64(stats.Sys) / ClocksPerSec, + Idle: float64(stats.Idle) / ClocksPerSec, + Irq: float64(stats.Intr) / ClocksPerSec, + }) } return ret, nil diff --git a/cpu/cpu_openbsd_386.go b/cpu/cpu_openbsd_386.go new file mode 100644 index 00000000..5e878399 --- /dev/null +++ b/cpu/cpu_openbsd_386.go @@ -0,0 +1,10 @@ +package cpu + +type cpuTimes struct { + User uint32 + Nice uint32 + Sys uint32 + Spin uint32 + Intr uint32 + Idle uint32 +} diff --git a/cpu/cpu_openbsd_amd64.go b/cpu/cpu_openbsd_amd64.go new file mode 100644 index 00000000..d659058c --- /dev/null +++ b/cpu/cpu_openbsd_amd64.go @@ -0,0 +1,10 @@ +package cpu + +type cpuTimes struct { + User uint64 + Nice uint64 + Sys uint64 + Spin uint64 + Intr uint64 + Idle uint64 +}