mirror of
https://github.com/golang/go
synced 2024-11-17 20:04:47 -07:00
internal/sysinfo: print cpu type from cpuinfo when internal cpu name is empty on Linux
Supports all linux operating systems. currently tested on x86, mips64le and loong64. Example output: $ go test -bench=.* goos: linux goarch: loong64 pkg: runtime cpu: Loongson-3A5000-HV @ 2500.00MHz BenchmarkSemTable/OneAddrCollision/n=1000 19261 62302 ns/op ... Change-Id: I02db12d70c11327e4625bb6e59f30dfaf37c2db0 Reviewed-on: https://go-review.googlesource.com/c/go/+/508735 Reviewed-by: Meidan Li <limeidan@loongson.cn> Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Bypass: Russ Cox <rsc@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
bcf83825ca
commit
6a1182027c
@ -22,7 +22,7 @@ import (
|
||||
|
||||
func main() {
|
||||
fmt.Printf("# GOARCH: %s\n", runtime.GOARCH)
|
||||
fmt.Printf("# CPU: %s\n", sysinfo.CPU.Name())
|
||||
fmt.Printf("# CPU: %s\n", sysinfo.CPUName())
|
||||
|
||||
fmt.Printf("# GOOS: %s\n", runtime.GOOS)
|
||||
ver, err := osinfo.Version()
|
||||
|
@ -564,7 +564,7 @@ var depsRules = `
|
||||
< net/rpc/jsonrpc;
|
||||
|
||||
# System Information
|
||||
internal/cpu, sync
|
||||
bufio, bytes, internal/cpu, io, os, strings, sync
|
||||
< internal/sysinfo;
|
||||
|
||||
# Test-only
|
||||
|
77
src/internal/sysinfo/cpuinfo_linux.go
Normal file
77
src/internal/sysinfo/cpuinfo_linux.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sysinfo
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func readLinuxProcCPUInfo(buf []byte) error {
|
||||
f, err := os.Open("/proc/cpuinfo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = io.ReadFull(f, buf)
|
||||
if err != nil && err != io.ErrUnexpectedEOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func osCpuInfoName() string {
|
||||
modelName := ""
|
||||
cpuMHz := ""
|
||||
|
||||
// The 512-byte buffer is enough to hold the contents of CPU0
|
||||
buf := make([]byte, 512)
|
||||
err := readLinuxProcCPUInfo(buf)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(buf))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if !strings.Contains(line, ":") {
|
||||
continue
|
||||
}
|
||||
|
||||
field := strings.SplitN(line, ": ", 2)
|
||||
switch strings.TrimSpace(field[0]) {
|
||||
case "Model Name", "model name":
|
||||
modelName = field[1]
|
||||
case "CPU MHz", "cpu MHz":
|
||||
cpuMHz = field[1]
|
||||
}
|
||||
}
|
||||
|
||||
if modelName == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if cpuMHz == "" {
|
||||
return modelName
|
||||
}
|
||||
|
||||
// The modelName field already contains the frequency information,
|
||||
// so the cpuMHz field information is not needed.
|
||||
// modelName filed example:
|
||||
// Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz
|
||||
f := [...]string{"GHz", "MHz"}
|
||||
for _, v := range f {
|
||||
if strings.Contains(modelName, v) {
|
||||
return modelName
|
||||
}
|
||||
}
|
||||
|
||||
return modelName + " @ " + cpuMHz + "MHz"
|
||||
}
|
11
src/internal/sysinfo/cpuinfo_stub.go
Normal file
11
src/internal/sysinfo/cpuinfo_stub.go
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !linux
|
||||
|
||||
package sysinfo
|
||||
|
||||
func osCpuInfoName() string {
|
||||
return ""
|
||||
}
|
@ -7,25 +7,29 @@
|
||||
package sysinfo
|
||||
|
||||
import (
|
||||
internalcpu "internal/cpu"
|
||||
"internal/cpu"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type cpuInfo struct {
|
||||
var cpuInfo struct {
|
||||
once sync.Once
|
||||
name string
|
||||
}
|
||||
|
||||
var CPU cpuInfo
|
||||
|
||||
func (cpu *cpuInfo) Name() string {
|
||||
cpu.once.Do(func() {
|
||||
func CPUName() string {
|
||||
cpuInfo.once.Do(func() {
|
||||
// Try to get the information from internal/cpu.
|
||||
if name := internalcpu.Name(); name != "" {
|
||||
cpu.name = name
|
||||
if name := cpu.Name(); name != "" {
|
||||
cpuInfo.name = name
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(martisch): use /proc/cpuinfo and /sys/devices/system/cpu/ on Linux as fallback.
|
||||
if name := osCpuInfoName(); name != "" {
|
||||
cpuInfo.name = name
|
||||
return
|
||||
}
|
||||
})
|
||||
return cpu.name
|
||||
|
||||
return cpuInfo.name
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ func (b *B) run() {
|
||||
if b.importPath != "" {
|
||||
fmt.Fprintf(b.w, "pkg: %s\n", b.importPath)
|
||||
}
|
||||
if cpu := sysinfo.CPU.Name(); cpu != "" {
|
||||
if cpu := sysinfo.CPUName(); cpu != "" {
|
||||
fmt.Fprintf(b.w, "cpu: %s\n", cpu)
|
||||
}
|
||||
})
|
||||
@ -668,7 +668,7 @@ func (b *B) Run(name string, f func(b *B)) bool {
|
||||
if b.importPath != "" {
|
||||
fmt.Printf("pkg: %s\n", b.importPath)
|
||||
}
|
||||
if cpu := sysinfo.CPU.Name(); cpu != "" {
|
||||
if cpu := sysinfo.CPUName(); cpu != "" {
|
||||
fmt.Printf("cpu: %s\n", cpu)
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user