|
|
|
@ -36,30 +36,30 @@ func Times(percpu bool) ([]TimesStat, error) {
|
|
|
|
|
func Info() ([]InfoStat, error) {
|
|
|
|
|
psrInfo, err := exec.LookPath("/usr/sbin/psrinfo")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot find psrinfo: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("cannot find psrinfo: %s", err)
|
|
|
|
|
}
|
|
|
|
|
psrInfoOut, err := invoke.Command(psrInfo, "-p", "-v")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot execute psrinfo: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("cannot execute psrinfo: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isaInfo, err := exec.LookPath("/usr/bin/isainfo")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot find isainfo: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("cannot find isainfo: %s", err)
|
|
|
|
|
}
|
|
|
|
|
isaInfoOut, err := invoke.Command(isaInfo, "-b", "-v")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot execute isainfo: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("cannot execute isainfo: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
procs, err := parseProcessorInfo(string(psrInfoOut))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Error parsing psrinfo output: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("error parsing psrinfo output: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flags, err := parseISAInfo(string(isaInfoOut))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Error parsing isainfo output: %s", err)
|
|
|
|
|
return nil, fmt.Errorf("error parsing isainfo output: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result := make([]InfoStat, 0, len(flags))
|
|
|
|
@ -79,7 +79,7 @@ func parseISAInfo(cmdOutput string) ([]string, error) {
|
|
|
|
|
|
|
|
|
|
// Sanity check the output
|
|
|
|
|
if len(words) < 4 || words[1] != "bit" || words[3] != "applications" {
|
|
|
|
|
return nil, errors.New("Attempted to parse invalid isainfo output")
|
|
|
|
|
return nil, errors.New("attempted to parse invalid isainfo output")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flags := make([]string, len(words)-4)
|
|
|
|
@ -94,15 +94,15 @@ func parseISAInfo(cmdOutput string) ([]string, error) {
|
|
|
|
|
var psrInfoMatch = regexp.MustCompile(`The physical processor has (?:([\d]+) virtual processor \(([\d]+)\)|([\d]+) cores and ([\d]+) virtual processors[^\n]+)\n(?:\s+ The core has.+\n)*\s+.+ \((\w+) ([\S]+) family (.+) model (.+) step (.+) clock (.+) MHz\)\n[\s]*(.*)`)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
psrNumCoresOffset = 1
|
|
|
|
|
psrNumCoresOffset = 1
|
|
|
|
|
psrNumCoresHTOffset = 3
|
|
|
|
|
psrNumHTOffset = 4
|
|
|
|
|
psrVendorIDOffset = 5
|
|
|
|
|
psrFamilyOffset = 7
|
|
|
|
|
psrModelOffset = 8
|
|
|
|
|
psrStepOffset = 9
|
|
|
|
|
psrClockOffset = 10
|
|
|
|
|
psrModelNameOffset = 11
|
|
|
|
|
psrNumHTOffset = 4
|
|
|
|
|
psrVendorIDOffset = 5
|
|
|
|
|
psrFamilyOffset = 7
|
|
|
|
|
psrModelOffset = 8
|
|
|
|
|
psrStepOffset = 9
|
|
|
|
|
psrClockOffset = 10
|
|
|
|
|
psrModelNameOffset = 11
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
@ -117,7 +117,7 @@ func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
|
if physicalCPU[psrStepOffset] != "" {
|
|
|
|
|
stepParsed, err := strconv.ParseInt(physicalCPU[psrStepOffset], 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot parse value %q for step as 32-bit integer: %s", physicalCPU[9], err)
|
|
|
|
|
return nil, fmt.Errorf("cannot parse value %q for step as 32-bit integer: %s", physicalCPU[9], err)
|
|
|
|
|
}
|
|
|
|
|
step = int32(stepParsed)
|
|
|
|
|
}
|
|
|
|
@ -125,7 +125,7 @@ func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
|
if physicalCPU[psrClockOffset] != "" {
|
|
|
|
|
clockParsed, err := strconv.ParseInt(physicalCPU[psrClockOffset], 10, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot parse value %q for clock as 32-bit integer: %s", physicalCPU[10], err)
|
|
|
|
|
return nil, fmt.Errorf("cannot parse value %q for clock as 32-bit integer: %s", physicalCPU[10], err)
|
|
|
|
|
}
|
|
|
|
|
clock = float64(clockParsed)
|
|
|
|
|
}
|
|
|
|
@ -137,7 +137,7 @@ func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
|
case physicalCPU[psrNumCoresOffset] != "":
|
|
|
|
|
numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresOffset], 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[1], err)
|
|
|
|
|
return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[1], err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < int(numCores); i++ {
|
|
|
|
@ -158,12 +158,12 @@ func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
|
case physicalCPU[psrNumCoresHTOffset] != "":
|
|
|
|
|
numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresHTOffset], 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[3], err)
|
|
|
|
|
return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[3], err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
numHT, err = strconv.ParseInt(physicalCPU[psrNumHTOffset], 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("Cannot parse value %q for hyperthread count as 32-bit integer: %s", physicalCPU[4], err)
|
|
|
|
|
return nil, fmt.Errorf("cannot parse value %q for hyperthread count as 32-bit integer: %s", physicalCPU[4], err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < int(numCores); i++ {
|
|
|
|
@ -182,7 +182,7 @@ func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
|
|
|
|
|
infoStatCount++
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return nil, errors.New("Values for cores with and without hyperthreading are both set")
|
|
|
|
|
return nil, errors.New("values for cores with and without hyperthreading are both set")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|