diff --git a/cpu/cpu.go b/cpu/cpu.go index 6b0034ec..e3a2c4c8 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -6,6 +6,13 @@ // various CPU architectures. package cpu +// Initialized reports whether the CPU features were initialized. +// +// For some GOOS/GOARCH combinations initialization of the CPU features depends +// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm +// Initialized will report false if reading the file fails. +var Initialized bool + // CacheLinePad is used to pad structs to avoid false sharing. type CacheLinePad struct{ _ [cacheLineSize]byte } diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index 33b61e52..76b5f507 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -28,7 +28,9 @@ var hwCap2 uint func init() { buf, err := ioutil.ReadFile(procAuxv) if err != nil { - panic("read proc auxv failed: " + err.Error()) + // e.g. on android /proc/self/auxv is not accessible, so silently + // ignore the error and leave Initialized = false + return } bo := hostByteOrder() @@ -52,4 +54,6 @@ func init() { } } doinit() + + Initialized = true } diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index e4b0f0d1..c0d8f640 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -13,6 +13,9 @@ import ( func TestAMD64minimalFeatures(t *testing.T) { if runtime.GOARCH == "amd64" { + if !cpu.Initialized { + t.Fatal("Initialized expected true, got false") + } if !cpu.X86.HasSSE2 { t.Fatal("HasSSE2 expected true, got false") } diff --git a/cpu/cpu_x86.go b/cpu/cpu_x86.go index 2b3ca2e1..d70d317f 100644 --- a/cpu/cpu_x86.go +++ b/cpu/cpu_x86.go @@ -9,6 +9,8 @@ package cpu const cacheLineSize = 64 func init() { + Initialized = true + maxID, _, _, _ := cpuid(0, 0) if maxID < 1 {