From 2ec35609d2152d006db9bf7d6cd278d37ab01dae Mon Sep 17 00:00:00 2001 From: Lomanic Date: Fri, 22 Feb 2019 20:59:16 +0100 Subject: [PATCH] [cpu][darwin] Remove calls to sysctl binary in cpu/cpu_darwin.go #639 Empirical benchmark (calling to cpu.Info): Lomanics-iMac:~ lomanic$ time ./cpu_info info 0: {"cpu":0,"vendorId":"GenuineIntel","family":"6","model":"30","stepping":5,"physicalId":"","coreId":"","cores":2,"modelName":"Intel(R) Core(TM) i5-6440HQ CPU @ 2.60GHz","mhz":2590,"cacheSize":256,"flags":["syscall","xd","em64t","lahf","lzcnt","prefetchw","rdtscp","tsci","fpu","vme","de","pse","tsc","msr","pae","mce","cx8","apic","sep","mtrr","pge","mca","cmov","pat","pse36","clfsh","mmx","fxsr","sse","sse2","htt","sse3","ssse3","cx16","sse4.1","sse4.2","popcnt","vmm"],"microcode":""} real 0m0.049s user 0m0.023s sys 0m0.041s Lomanics-iMac:~ lomanic$ time ./cpu_info.fixed info 0: {"cpu":0,"vendorId":"GenuineIntel","family":"6","model":"30","stepping":5,"physicalId":"","coreId":"","cores":2,"modelName":"Intel(R) Core(TM) i5-6440HQ CPU @ 2.60GHz","mhz":2590,"cacheSize":256,"flags":["fpu","vme","de","pse","tsc","msr","pae","mce","cx8","apic","sep","mtrr","pge","mca","cmov","pat","pse36","clfsh","mmx","fxsr","sse","sse2","htt","sse3","ssse3","cx16","sse4.1","sse4.2","popcnt","vmm","syscall","xd","em64t","lahf","lzcnt","prefetchw","rdtscp","tsci"],"microcode":""} real 0m0.010s user 0m0.004s sys 0m0.006s --- cpu/cpu_darwin.go | 90 +++++++++++++++++++------------------------------------ 1 file changed, 31 insertions(+), 59 deletions(-) diff --git a/cpu/cpu_darwin.go b/cpu/cpu_darwin.go index 74d2737..797297f 100644 --- a/cpu/cpu_darwin.go +++ b/cpu/cpu_darwin.go @@ -4,9 +4,10 @@ package cpu import ( "context" - "os/exec" "strconv" "strings" + + "golang.org/x/sys/unix" ) // sys/resource.h @@ -41,75 +42,46 @@ func Info() ([]InfoStat, error) { func InfoWithContext(ctx context.Context) ([]InfoStat, error) { var ret []InfoStat - sysctl, err := exec.LookPath("/usr/sbin/sysctl") - if err != nil { - return ret, err - } - out, err := invoke.CommandWithContext(ctx, sysctl, "machdep.cpu") - if err != nil { - return ret, err - } c := InfoStat{} - for _, line := range strings.Split(string(out), "\n") { - values := strings.Fields(line) - if len(values) < 1 { - continue + c.ModelName, _ = unix.Sysctl("machdep.cpu.brand_string") + family, _ := unix.SysctlUint32("machdep.cpu.family") + c.Family = strconv.FormatUint(uint64(family), 10) + model, _ := unix.SysctlUint32("machdep.cpu.model") + c.Model = strconv.FormatUint(uint64(model), 10) + stepping, _ := unix.SysctlUint32("machdep.cpu.stepping") + c.Stepping = int32(stepping) + features, err := unix.Sysctl("machdep.cpu.features") + if err == nil { + for _, v := range strings.Fields(features) { + c.Flags = append(c.Flags, strings.ToLower(v)) } - - t, err := strconv.ParseInt(values[1], 10, 64) - // err is not checked here because some value is string. - if strings.HasPrefix(line, "machdep.cpu.brand_string") { - c.ModelName = strings.Join(values[1:], " ") - } else if strings.HasPrefix(line, "machdep.cpu.family") { - c.Family = values[1] - } else if strings.HasPrefix(line, "machdep.cpu.model") { - c.Model = values[1] - } else if strings.HasPrefix(line, "machdep.cpu.stepping") { - if err != nil { - return ret, err - } - c.Stepping = int32(t) - } else if strings.HasPrefix(line, "machdep.cpu.features") { - for _, v := range values[1:] { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if strings.HasPrefix(line, "machdep.cpu.leaf7_features") { - for _, v := range values[1:] { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if strings.HasPrefix(line, "machdep.cpu.extfeatures") { - for _, v := range values[1:] { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if strings.HasPrefix(line, "machdep.cpu.core_count") { - if err != nil { - return ret, err - } - c.Cores = int32(t) - } else if strings.HasPrefix(line, "machdep.cpu.cache.size") { - if err != nil { - return ret, err - } - c.CacheSize = int32(t) - } else if strings.HasPrefix(line, "machdep.cpu.vendor") { - c.VendorID = values[1] + } + leaf7Features, err := unix.Sysctl("machdep.cpu.leaf7_features") + if err == nil { + for _, v := range strings.Fields(leaf7Features) { + c.Flags = append(c.Flags, strings.ToLower(v)) + } + } + extfeatures, err := unix.Sysctl("machdep.cpu.extfeatures") + if err == nil { + for _, v := range strings.Fields(extfeatures) { + c.Flags = append(c.Flags, strings.ToLower(v)) } } + cores, _ := unix.SysctlUint32("machdep.cpu.core_count") + c.Cores = int32(cores) + cacheSize, _ := unix.SysctlUint32("machdep.cpu.cache.size") + c.CacheSize = int32(cacheSize) + c.VendorID, _ = unix.Sysctl("machdep.cpu.vendor") // Use the rated frequency of the CPU. This is a static value and does not // account for low power or Turbo Boost modes. - out, err = invoke.CommandWithContext(ctx, sysctl, "hw.cpufrequency") - if err != nil { - return ret, err - } - - values := strings.Fields(string(out)) - hz, err := strconv.ParseFloat(values[1], 64) + cpuFrequency, err := unix.SysctlUint64("hw.cpufrequency") if err != nil { return ret, err } - c.Mhz = hz / 1000000.0 + c.Mhz = float64(cpuFrequency) / 1000000.0 return append(ret, c), nil }