Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions cpuinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,26 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
scanner := bufio.NewScanner(bytes.NewReader(info))

firstLine := firstNonEmptyLine(scanner)
if !strings.HasPrefix(firstLine, "Processor") || !strings.Contains(firstLine, ":") {
match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
if !match || !strings.Contains(firstLine, ":") {
return nil, errors.New("invalid cpuinfo file: " + firstLine)
}
field := strings.SplitN(firstLine, ": ", 2)
commonCPUInfo := CPUInfo{VendorID: field[1]}

cpuinfo := []CPUInfo{}
i := -1
featuresLine := ""
commonCPUInfo := CPUInfo{}
i := 0
if strings.TrimSpace(field[0]) == "Processor" {
commonCPUInfo = CPUInfo{ModelName: field[1]}
i = -1
} else {
v, err := strconv.ParseUint(field[1], 0, 32)
if err != nil {
return nil, err
}
firstcpu := CPUInfo{Processor: uint(v)}
cpuinfo = []CPUInfo{firstcpu}
}

for scanner.Scan() {
line := scanner.Text()
Expand All @@ -216,20 +227,28 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
}
cpuinfo[i].Processor = uint(v)
case "BogoMIPS":
if i == -1 {
cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor
i++
cpuinfo[i].Processor = 0
}
v, err := strconv.ParseFloat(field[1], 64)
if err != nil {
return nil, err
}
cpuinfo[i].BogoMips = v
case "Features":
featuresLine = line
case "model name":
cpuinfo[i].ModelName = field[1]
}
}
fields := strings.SplitN(featuresLine, ": ", 2)
for i := range cpuinfo {
cpuinfo[i].Flags = strings.Fields(fields[1])
}
return cpuinfo, nil

}

func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
Expand Down
99 changes: 95 additions & 4 deletions cpuinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package procfs
import "testing"

const (
cpuinfoArm7 = `
cpuinfoArm7Legacy = `
Processor : ARMv7 Processor rev 5 (v7l)
processor : 0
BogoMIPS : 2400.00
Expand All @@ -37,6 +37,65 @@ Hardware : sun8i
Revision : 0000
Serial : 5400503583203c3c040e`

cpuinfoArm7LegacyV1 = `
Processor : ARMv6-compatible processor rev 5 (v6l)
BogoMIPS : 791.34
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0x41
CPU architecture: 6TEJ
CPU variant : 0x1
CPU part : 0xb36
CPU revision : 5

Hardware : IMAPX200
Revision : 0000
Serial : 0000000000000000`

cpuinfoArm7 = `
processor : 0
model name : ARMv7 Processor rev 3 (v7l)
BogoMIPS : 108.00
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd08
CPU revision : 3

processor : 1
model name : ARMv7 Processor rev 3 (v7l)
BogoMIPS : 108.00
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd08
CPU revision : 3

processor : 2
model name : ARMv7 Processor rev 3 (v7l)
BogoMIPS : 108.00
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd08
CPU revision : 3

processor : 3
model name : ARMv7 Processor rev 3 (v7l)
BogoMIPS : 108.00
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd08
CPU revision : 3

Hardware : BCM2835
Revision : c03111
`

cpuinfoS390x = `
vendor_id : IBM/S390
# processors : 4
Expand Down Expand Up @@ -153,22 +212,54 @@ func TestCPUInfoX86(t *testing.T) {
}
}

func TestCPUInfoParseARM(t *testing.T) {
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
func TestCPUInfoParseARMLegacy(t *testing.T) {
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7Legacy))
if err != nil || cpuinfo == nil {
t.Fatalf("unable to parse arm cpu info: %v", err)
}
if want, have := 2, len(cpuinfo); want != have {
t.Errorf("want number of processors %v, have %v", want, have)
}
if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].VendorID; want != have {
if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].ModelName; want != have {
t.Errorf("want vendor %v, have %v", want, have)
}
if want, have := "thumb", cpuinfo[1].Flags[2]; want != have {
t.Errorf("want flag %v, have %v", want, have)
}
}

func TestCPUInfoParseARMLegacyV1(t *testing.T) {
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7LegacyV1))
if err != nil || cpuinfo == nil {
t.Fatalf("unable to parse arm cpu info: %v", err)
}
if want, have := 1, len(cpuinfo); want != have {
t.Errorf("want number of processors %v, have %v", want, have)
}
if want, have := "ARMv6-compatible processor rev 5 (v6l)", cpuinfo[0].ModelName; want != have {
t.Errorf("want vendor %v, have %v", want, have)
}
if want, have := "thumb", cpuinfo[0].Flags[2]; want != have {
t.Errorf("want flag %v, have %v", want, have)
}
}

func TestCPUInfoParseARM(t *testing.T) {
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
if err != nil || cpuinfo == nil {
t.Fatalf("unable to parse arm cpu info: %v", err)
}
if want, have := 4, len(cpuinfo); want != have {
t.Errorf("want number of processors %v, have %v", want, have)
}
if want, have := "ARMv7 Processor rev 3 (v7l)", cpuinfo[0].ModelName; want != have {
t.Errorf("want vendor %v, have %v", want, have)
}
if want, have := "thumb", cpuinfo[1].Flags[1]; want != have {
t.Errorf("want flag %v, have %v", want, have)
}
}

func TestCPUInfoParseS390X(t *testing.T) {
cpuinfo, err := parseCPUInfoS390X([]byte(cpuinfoS390x))
if err != nil || cpuinfo == nil {
Expand Down