From eb5bfca90274a3896a9ea0ec11261716683bd84e Mon Sep 17 00:00:00 2001 From: WAKAYAMA shirou Date: Sun, 29 Jan 2017 01:23:21 +0900 Subject: [PATCH] [cpu]freebsd: cpu.Info() now returns CPUInfos same number as CPU nums. --- cpu/cpu_freebsd.go | 38 +++++++++++++++++++----- cpu/cpu_test.go | 30 +++++++++++++++++++ cpu/expected/freebsd/1cpu_2core.txt | 43 +++++++++++++++++++++++++++ cpu/expected/freebsd/1cpu_4core.txt | 38 ++++++++++++++++++++++++ cpu/expected/freebsd/2cpu_4core.txt | 45 +++++++++++++++++++++++++++++ 5 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 cpu/expected/freebsd/1cpu_2core.txt create mode 100644 cpu/expected/freebsd/1cpu_4core.txt create mode 100644 cpu/expected/freebsd/2cpu_4core.txt diff --git a/cpu/cpu_freebsd.go b/cpu/cpu_freebsd.go index 25037927..5834d6e1 100644 --- a/cpu/cpu_freebsd.go +++ b/cpu/cpu_freebsd.go @@ -26,6 +26,7 @@ var originMatch = regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Fami var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`) var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`) var cpuEnd = regexp.MustCompile(`^Trying to mount root`) +var cpuCores = regexp.MustCompile(`FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)`) func init() { getconf, err := exec.LookPath("/usr/bin/getconf") @@ -107,11 +108,12 @@ func Times(percpu bool) ([]TimesStat, error) { // are the same across CPUs. func Info() ([]InfoStat, error) { const dmesgBoot = "/var/run/dmesg.boot" - lines, _ := common.ReadLines(dmesgBoot) - c := InfoStat{} + c, num, err := parseDmesgBoot(dmesgBoot) + if err != nil { + return nil, err + } var vals []string - var err error if vals, err = common.DoSysctrl("hw.clockrate"); err != nil { return nil, err } @@ -133,19 +135,28 @@ func Info() ([]InfoStat, error) { } c.ModelName = strings.Join(vals, " ") - var cpuNums int32 + ret := make([]InfoStat, num) + for i := 0; i < num; i++ { + ret[i] = c + } + + return ret, nil +} + +func parseDmesgBoot(fileName string) (InfoStat, int, error) { + c := InfoStat{} + lines, _ := common.ReadLines(fileName) + var cpuNum int for _, line := range lines { if matches := cpuEnd.FindStringSubmatch(line); matches != nil { break - } else if matches := cpuMatch.FindStringSubmatch(line); matches != nil { - c.CPU = cpuNums } else if matches := originMatch.FindStringSubmatch(line); matches != nil { c.VendorID = matches[1] c.Family = matches[3] c.Model = matches[4] t, err := strconv.ParseInt(matches[5], 10, 32) if err != nil { - return nil, fmt.Errorf("Unable to parse FreeBSD CPU stepping information from %q: %v", line, err) + return c, 0, fmt.Errorf("Unable to parse FreeBSD CPU stepping information from %q: %v", line, err) } c.Stepping = int32(t) } else if matches := featuresMatch.FindStringSubmatch(line); matches != nil { @@ -156,8 +167,19 @@ func Info() ([]InfoStat, error) { for _, v := range strings.Split(matches[1], ",") { c.Flags = append(c.Flags, strings.ToLower(v)) } + } else if matches := cpuCores.FindStringSubmatch(line); matches != nil { + t, err := strconv.ParseInt(matches[1], 10, 32) + if err != nil { + return c, 0, fmt.Errorf("Unable to parse FreeBSD CPU Nums from %q: %v", line, err) + } + cpuNum = int(t) + t2, err := strconv.ParseInt(matches[2], 10, 32) + if err != nil { + return c, 0, fmt.Errorf("Unable to parse FreeBSD CPU cores from %q: %v", line, err) + } + c.Cores = int32(t2) } } - return []InfoStat{c}, nil + return c, cpuNum, nil } diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index 6082ffcc..66c19351 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -3,9 +3,12 @@ package cpu import ( "fmt" "os" + "path/filepath" "runtime" "testing" "time" + + "github.com/shirou/gopsutil/internal/common" ) func TestCpu_times(t *testing.T) { @@ -62,6 +65,33 @@ func TestCpuInfo(t *testing.T) { } } +func TestParseDmesgBoot(t *testing.T) { + var cpuTests = []struct { + file string + cpuNum int + cores int32 + }{ + {"1cpu_2core.txt", 1, 2}, + {"1cpu_4core.txt", 1, 4}, + {"2cpu_4core.txt", 2, 4}, + } + for _, tt := range cpuTests { + v, num, err := parseDmesgBoot(filepath.Join("expected/freebsd/", tt.file)) + if err != nil { + t.Errorf("parseDmesgBoot failed(%s), %v", tt.file, err) + } + if num != tt.cpuNum { + t.Errorf("parseDmesgBoot wrong length(%s), %v", tt.file, err) + } + if v.Cores != tt.cores { + t.Errorf("parseDmesgBoot wrong core(%s), %v", tt.file, err) + } + if !common.StringsContains(v.Flags, "fpu") { + t.Errorf("parseDmesgBoot fail to parse features(%s), %v", tt.file, err) + } + } +} + func testCPUPercent(t *testing.T, percpu bool) { numcpu := runtime.NumCPU() testCount := 3 diff --git a/cpu/expected/freebsd/1cpu_2core.txt b/cpu/expected/freebsd/1cpu_2core.txt new file mode 100644 index 00000000..a5d9fec3 --- /dev/null +++ b/cpu/expected/freebsd/1cpu_2core.txt @@ -0,0 +1,43 @@ +Copyright (c) 1992-2016 The FreeBSD Project. +Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 + The Regents of the University of California. All rights reserved. +FreeBSD is a registered trademark of The FreeBSD Foundation. +FreeBSD 11.0-RELEASE-p2 #0: Mon Oct 24 06:55:27 UTC 2016 + root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 +FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0) +VT(vga): resolution 640x480 +CPU: Intel(R) Core(TM) i3 CPU 550 @ 3.20GHz (3192.07-MHz K8-class CPU) + Origin="GenuineIntel" Id=0x20655 Family=0x6 Model=0x25 Stepping=5 + Features=0xbfebfbff + Features2=0x9ae3bd + AMD Features=0x28100800 + AMD Features2=0x1 + VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID + TSC: P-state invariant, performance statistics +real memory = 8589934592 (8192 MB) +avail memory = 8046452736 (7673 MB) +Event timer "LAPIC" quality 600 +ACPI APIC Table: +FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs +FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 hardware threads +random: unblocking device. +ioapic0 irqs 0-23 on motherboard +random: entropy device external interface +kbd1 at kbdmux0 +netmap: loaded module +module_register_init: MOD_LOAD (vesa, 0xffffffff8101c970, 0) error 19 +vtvga0: on motherboard +cryptosoft0: on motherboard +aesni0: No AESNI support. +acpi0: on motherboard +acpi0: Power Button (fixed) +cpu0: on acpi0 +ACPI BIOS Warning (bug): Incorrect checksum in table [SSDT] - 0x3F, should be 0x1F (20160527/tbprint-229) +cpu1: on acpi0 +cpu2: on acpi0 +cpu3: on acpi0 +attimer0: port 0x40-0x43 irq 0 on acpi0 +Timecounter "i8254" frequency 1193182 Hz quality 0 +Event timer "i8254" frequency 1193182 Hz quality 100 +atrtc0: port 0x70-0x71 irq 8 on acpi0 +Event timer "RTC" frequency 32768 Hz quality 0 \ No newline at end of file diff --git a/cpu/expected/freebsd/1cpu_4core.txt b/cpu/expected/freebsd/1cpu_4core.txt new file mode 100644 index 00000000..2a498235 --- /dev/null +++ b/cpu/expected/freebsd/1cpu_4core.txt @@ -0,0 +1,38 @@ +Copyright (c) 1992-2016 The FreeBSD Project. +Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 + The Regents of the University of California. All rights reserved. +FreeBSD is a registered trademark of The FreeBSD Foundation. +FreeBSD 10.3-RELEASE-p4 #0: Sat May 28 12:23:44 UTC 2016 + root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 +FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512 +CPU: Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70GHz (3700.09-MHz K8-class CPU) + Origin="GenuineIntel" Id=0x306e4 Family=0x6 Model=0x3e Stepping=4 + Features=0xbfebfbff + Features2=0x7fbee3ff + AMD Features=0x2c100800 + AMD Features2=0x1 + Structured Extended Features=0x281 + XSAVE Features=0x1 + VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr + TSC: P-state invariant, performance statistics +real memory = 34368126976 (32776 MB) +avail memory = 33228333056 (31689 MB) +Event timer "LAPIC" quality 600 +ACPI APIC Table: < > +FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs +FreeBSD/SMP: 1 package(s) x 4 core(s) x 2 SMT threads + cpu0 (BSP): APIC ID: 0 + cpu1 (AP): APIC ID: 1 + cpu2 (AP): APIC ID: 2 + cpu3 (AP): APIC ID: 3 + cpu4 (AP): APIC ID: 4 + cpu5 (AP): APIC ID: 5 + cpu6 (AP): APIC ID: 6 + cpu7 (AP): APIC ID: 7 +random: initialized +ioapic0 irqs 0-23 on motherboard +ioapic1 irqs 24-47 on motherboard +kbd1 at kbdmux0 +cryptosoft0: on motherboard +aesni0: on motherboard +acpi0: on motherboard \ No newline at end of file diff --git a/cpu/expected/freebsd/2cpu_4core.txt b/cpu/expected/freebsd/2cpu_4core.txt new file mode 100644 index 00000000..b274cc4f --- /dev/null +++ b/cpu/expected/freebsd/2cpu_4core.txt @@ -0,0 +1,45 @@ +Copyright (c) 1992-2011 The FreeBSD Project. +Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 + The Regents of the University of California. All rights reserved. +FreeBSD is a registered trademark of The FreeBSD Foundation. +FreeBSD 8.2-RELEASE #1: Sat Mar 5 23:03:14 CET 2011 + root@host1:/usr/obj/usr/src/sys/MYKERNEL amd64 +Timecounter "i8254" frequency 1193182 Hz quality 0 +CPU: Intel(R) Xeon(R) CPU E5420 @ 2.50GHz (2500.11-MHz K8-class CPU) + Origin = "GenuineIntel" Id = 0x10676 Family = 6 Model = 17 Stepping = 6 + Features=0xbfebfbff + Features2=0xce3bd + AMD Features=0x20100800 + AMD Features2=0x1 + TSC: P-state invariant +real memory = 17179869184 (16384 MB) +avail memory = 16531587072 (15765 MB) +ACPI APIC Table: +FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs +FreeBSD/SMP: 2 package(s) x 4 core(s) + cpu0 (BSP): APIC ID: 0 + cpu1 (AP): APIC ID: 1 + cpu2 (AP): APIC ID: 2 + cpu3 (AP): APIC ID: 3 + cpu4 (AP): APIC ID: 4 + cpu5 (AP): APIC ID: 5 + cpu6 (AP): APIC ID: 6 + cpu7 (AP): APIC ID: 7 +ioapic0 irqs 0-23 on motherboard +ioapic1 irqs 24-47 on motherboard +kbd1 at kbdmux0 +acpi0: on motherboard +acpi0: [ITHREAD] +acpi0: Power Button (fixed) +unknown: I/O range not supported +Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 +acpi_timer0: <24-bit timer at 3.579545MHz> port 0x1008-0x100b on acpi0 +cpu0: on acpi0 +cpu1: on acpi0 +cpu2: on acpi0 +cpu3: on acpi0 +cpu4: on acpi0 +cpu5: on acpi0 +cpu6: on acpi0 +cpu7: on acpi0 +pcib0: port 0xcf8-0xcff on acpi0 \ No newline at end of file