don't make assumptions on which CPUs are online and wich aren't based
on hw.smt and hw.ncpuonline. Rather, use KERN_CPUSTATS to get the CPU
statistics, which includes a flag field that can tell us if that CPU
is online or not.
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.
Currently, ClocksPerSec is determined by exec'ing getconf in func init,
i.e. on startup of every program importing the package. getconf might
not be present on some systems or is not executable by the current user.
To avoid this hard to control dependency, use the
github.com/tklauser/go-sysconf package which implements sysconf(3)
entirely in Go without cgo. The package is supported on all platforms
currently supported by the cpu and v3/cpu package of gopsutil.
Use SysctlUvmexp from golang.org/x/sys/unix to avoid having to simplify
the implementation of cpu.InfoWithContext
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
When hw.smt is enabled, and it's enabled by default from 6.4, the
number of cpus given by `runtime.NumCPU()` is half of the total: only
the cpuN with N = 0,2,4,... are used by the system. We need to detect
that and ask for the correct stats.
Fix: get cptime of n-th cpu when `percpu` instead of the average.
While there, rearrange the last if statement to make the code a bit
more homogeneous.