]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: run on GOARM=5 and GOARM=6 uniprocessor freebsd/arm systems
authorRuss Cox <rsc@golang.org>
Fri, 7 Aug 2015 15:48:52 +0000 (11:48 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 7 Aug 2015 17:39:07 +0000 (17:39 +0000)
Also, crash early on non-Linux SMP ARM systems when GOARM < 7;
without the proper synchronization, SMP cannot work.

Linux is okay because we call kernel-provided routines for
synchronization and barriers, and the kernel takes care of
providing the right routines for the current system.
On non-Linux systems we are left to fend for ourselves.

It is possible to use different synchronization on GOARM=6,
but it's too late to do that in the Go 1.5 cycle.
We don't believe there are any non-Linux SMP GOARM=6 systems anyway.

Fixes #12067.

Change-Id: I771a556e47893ed540ec2cd33d23c06720157ea3
Reviewed-on: https://go-review.googlesource.com/13363
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/asm_arm.s
src/runtime/os1_darwin.go
src/runtime/os_darwin_arm.go
src/runtime/os_freebsd_arm.go
src/runtime/os_linux_arm.go
src/runtime/os_nacl_arm.go
src/runtime/os_netbsd_arm.go
src/runtime/os_openbsd_arm.go
src/runtime/runtime2.go

index 91dccdc3811aaee8132c078c936c5857618d4205..9c32e42afd701148e16f8491b07bfb0e650f2779 100644 (file)
@@ -752,6 +752,8 @@ TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
        B       runtime·atomicstore(SB)
 
 // armPublicationBarrier is a native store/store barrier for ARMv7+.
+// On earlier ARM revisions, armPublicationBarrier is a no-op.
+// This will not work on SMP ARMv6 machines, if any are in use.
 // To implement publiationBarrier in sys_$GOOS_arm.s using the native
 // instructions, use:
 //
@@ -759,6 +761,9 @@ TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
 //             B       runtime·armPublicationBarrier(SB)
 //
 TEXT runtime·armPublicationBarrier(SB),NOSPLIT,$-4-0
+       MOVB    runtime·goarm(SB), R11
+       CMP     $7, R11
+       BLT     2(PC)
        WORD $0xf57ff05e        // DMB ST
        RET
 
index 08ec611d431469c3960d6bfa30184aaf015e237c..e07022997c81b56b79e150a154e8b81325afb75b 100644 (file)
@@ -34,14 +34,19 @@ func osinit() {
        // bsdthread_register delayed until end of goenvs so that we
        // can look at the environment first.
 
+       ncpu = getncpu()
+}
+
+func getncpu() int32 {
        // Use sysctl to fetch hw.ncpu.
        mib := [2]uint32{6, 3}
        out := uint32(0)
        nout := unsafe.Sizeof(out)
        ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
-       if ret >= 0 {
-               ncpu = int32(out)
+       if ret >= 0 && int32(out) > 0 {
+               return int32(out)
        }
+       return 1
 }
 
 var urandom_dev = []byte("/dev/urandom\x00")
index d3336c012a0b73720c42bb96ff364400748af5da..1ccc9592da8647c0856aba3f622a893138ee8be6 100644 (file)
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-       return // TODO(minux)
+       // TODO(minux): FP checks like in os_linux_arm.go.
+
+       // osinit not called yet, so ncpu not set: must use getncpu directly.
+       if getncpu() > 1 && goarm < 7 {
+               print("runtime: this system has multiple CPUs and must use\n")
+               print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+               exit(1)
+       }
 }
 
 //go:nosplit
index e049cbf9a1ee5aaf8738b2e016f64fdf4582bdfb..1f2add279f214b00fed221fe66aefdcff99a62a1 100644 (file)
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-       // TODO(minux)
+       // TODO(minux): FP checks like in os_linux_arm.go.
+
+       // osinit not called yet, so ncpu not set: must use getncpu directly.
+       if getncpu() > 1 && goarm < 7 {
+               print("runtime: this system has multiple CPUs and must use\n")
+               print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+               exit(1)
+       }
 }
 
 //go:nosplit
index 6c74c818595f747379ac4c0b4c7a1582938eb663..3749640ee52182c125ea3b5035bab64c3ff3194c 100644 (file)
@@ -19,7 +19,6 @@ const (
 var randomNumber uint32
 var armArch uint8 = 6 // we default to ARMv6
 var hwcap uint32      // set by setup_auxv
-var goarm uint8       // set by 5l
 
 func checkgoarm() {
        if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
index a43e7c47b7a5fac9d4b7de0148f10f2fba2e3a2d..f94c183e87684c59b9f5ba65ec340c668f6918af 100644 (file)
@@ -5,7 +5,13 @@
 package runtime
 
 func checkgoarm() {
-       return // NaCl/ARM only supports ARMv7
+       // TODO(minux): FP checks like in os_linux_arm.go.
+
+       // NaCl/ARM only supports ARMv7
+       if goarm != 7 {
+               print("runtime: NaCl requires ARMv7. Recompile using GOARM=7.\n")
+               exit(1)
+       }
 }
 
 //go:nosplit
index 83c4c06cf93597661e6ae6b5e39521282343463d..03032e8bea53bf492b221a63c4ed4fd9349b7f3b 100644 (file)
@@ -16,7 +16,14 @@ func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintp
 }
 
 func checkgoarm() {
-       // TODO(minux)
+       // TODO(minux): FP checks like in os_linux_arm.go.
+
+       // osinit not called yet, so ncpu not set: must use getncpu directly.
+       if getncpu() > 1 && goarm < 7 {
+               print("runtime: this system has multiple CPUs and must use\n")
+               print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+               exit(1)
+       }
 }
 
 //go:nosplit
index be3f330dfb0b6e27a2e13c9f0ccec2f436915106..b46fef0090d23d39325326e052b04c9ea066723a 100644 (file)
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-       // TODO(minux)
+       // TODO(minux): FP checks like in os_linux_arm.go.
+
+       // osinit not called yet, so ncpu not set: must use getncpu directly.
+       if getncpu() > 1 && goarm < 7 {
+               print("runtime: this system has multiple CPUs and must use\n")
+               print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+               exit(1)
+       }
 }
 
 //go:nosplit
index a157f016d162c5282f131709c2483f8f0d5f3e10..57cd869d88c0c795b9bcde49165c5d487a1ef721 100644 (file)
@@ -645,6 +645,8 @@ var (
        cpuid_ecx         uint32
        cpuid_edx         uint32
        lfenceBeforeRdtsc bool
+
+       goarm uint8 // set by cmd/link on arm systems
 )
 
 // Set by the linker so the runtime can determine the buildmode.