This PR adds support for reading the frequency of Apple Silicon
M1/M2 CPUs. We do so by reading the values out of the IOKit
framework, as a few other projects have now demonstrated to be
possible. This requires the use of CGO. The library provides a
convenience IsAppleSilicon() guard to detect whether the values
can be read.
Currently gopsutil does not support the big.LITTLE CPU architectures
(i think?) - in fact the P and E cores have different max frequencies.
For now, just read the P core frequency. The E core data is readily
available if we want to read it in the future.
Closes #1000
Small example program
```go
package main
import (
"fmt"
"github.com/shoenig/go-m1cpu"
"github.com/shirou/gopsutil/v3/cpu"
)
func main() {
fmt.Println("is Apple Silicon:", m1cpu.IsAppleSilicon())
fmt.Println("model name", m1cpu.ModelName())
fmt.Println("pCore GHz", m1cpu.PCoreGHz())
fmt.Println("eCore GHz", m1cpu.ECoreGHz())
fmt.Println("pCore Hz", m1cpu.PCoreHz())
fmt.Println("eCore Hz", m1cpu.ECoreHz())
fmt.Println("----- gopsutil ----")
infos, err := cpu.Info()
if err != nil {
panic(err)
}
for _, info := range infos {
fmt.Println("info.Mhz", info.Mhz)
}
}
```
```shell
go run main.go
is Apple Silicon: true
model name Apple M2 Pro
pCore GHz 3.504
eCore GHz 2.424
pCore Hz 3504000000
eCore Hz 2424000000
----- gopsutil ----
info.Mhz 3.504e+09
```
This commit replaces `os.Setenv` with `t.Setenv` in tests. The
environment variable is automatically restored to its original value
when the test and all its subtests complete.
Reference: https://pkg.go.dev/testing#T.Setenv
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
Use GetActiveProcessorCount and the ALL_PROCESSOR_GROUPS const provided
in golang.org/x/sys/windows. The function is available on Windows 7 and
later. Go requires Windows 7, see https://go.dev/doc/go1.11#ports
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.
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.
updated win32_Processor struct to exclude loadpercentage field.
The loadpercentage takes linearly more time as the # of sockets
increases. By default vSphere maps 1 vCPU to 1 socket, resulting in very
poor performance when getting CPU info against, saying, 40 vCPU VM
(basically 40 sockets as seen by the VM).