1
0
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:
Guoqi Chen 2023-07-11 05:11:26 +08:00 committed by Gopher Robot
parent bcf83825ca
commit 6a1182027c
6 changed files with 105 additions and 13 deletions

View File

@ -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()

View File

@ -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

View 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"
}

View 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 ""
}

View File

@ -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
}

View File

@ -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)
}
})