aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2021-01-31 04:21:47 +1100
committerJoel Sing <joel@sing.id.au>2021-05-09 17:05:25 +0000
commit8ec8f6aa87569a6bc567d4a7039fc22a473b37ec (patch)
treea1fe1f8e3b60aa55f98b0eb4be5ff5bf0253f4a1
parent5203357ebacf9f41ca5e194d953c164049172e96 (diff)
downloadgo-8ec8f6aa87569a6bc567d4a7039fc22a473b37ec.tar.gz
go-8ec8f6aa87569a6bc567d4a7039fc22a473b37ec.zip
runtime: switch openbsd/arm to pthreads
This switches openbsd/arm to thread creation via pthreads, rather than doing direct system calls. Update #36435 Change-Id: Ia8749e3723a9967905c33b6d93dfd9be797a486c Reviewed-on: https://go-review.googlesource.com/c/go/+/315790 Trust: Joel Sing <joel@sing.id.au> Reviewed-by: Cherry Mui <cherryyz@google.com>
-rw-r--r--src/runtime/asm_arm.s13
-rw-r--r--src/runtime/defs_openbsd_arm.go9
-rw-r--r--src/runtime/os_openbsd_libc.go4
-rw-r--r--src/runtime/os_openbsd_syscall.go4
-rw-r--r--src/runtime/proc.go2
-rw-r--r--src/runtime/sys_libc.go4
-rw-r--r--src/runtime/sys_openbsd.go4
-rw-r--r--src/runtime/sys_openbsd_arm.s207
8 files changed, 153 insertions, 94 deletions
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index e779fc8f84..6d3573d68f 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -142,6 +142,11 @@ TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
BL runtime·emptyfunc(SB) // fault if stack check is wrong
+#ifdef GOOS_openbsd
+ // Save g to TLS so that it is available from signal trampoline.
+ BL runtime·save_g(SB)
+#endif
+
BL runtime·_initcgo(SB) // will clobber R0-R3
// update stackguard after _cgo_init
@@ -633,9 +638,13 @@ TEXT ·cgocallback(SB),NOSPLIT,$12-12
NO_LOCAL_POINTERS
// Load m and g from thread-local storage.
+#ifdef GOOS_openbsd
+ BL runtime·load_g(SB)
+#else
MOVB runtime·iscgo(SB), R0
CMP $0, R0
BL.NE runtime·load_g(SB)
+#endif
// If g is nil, Go did not create the current thread.
// Call needm to obtain one for temporary use.
@@ -745,6 +754,9 @@ TEXT setg<>(SB),NOSPLIT|NOFRAME,$0-0
#ifdef GOOS_windows
B runtime·save_g(SB)
#else
+#ifdef GOOS_openbsd
+ B runtime·save_g(SB)
+#else
MOVB runtime·iscgo(SB), R0
CMP $0, R0
B.EQ 2(PC)
@@ -753,6 +765,7 @@ TEXT setg<>(SB),NOSPLIT|NOFRAME,$0-0
MOVW g, R0
RET
#endif
+#endif
TEXT runtime·emptyfunc(SB),0,$0-0
RET
diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
index 170bb3876c..9b84b5a3a3 100644
--- a/src/runtime/defs_openbsd_arm.go
+++ b/src/runtime/defs_openbsd_arm.go
@@ -30,6 +30,8 @@ const (
_SA_RESTART = 0x2
_SA_ONSTACK = 0x1
+ _PTHREAD_CREATE_DETACHED = 0x1
+
_SIGHUP = 0x1
_SIGINT = 0x2
_SIGQUIT = 0x3
@@ -174,3 +176,10 @@ type keventt struct {
udata *byte
pad_cgo_1 [4]byte
}
+
+type pthread uintptr
+type pthreadattr uintptr
+type pthreadcond uintptr
+type pthreadcondattr uintptr
+type pthreadmutex uintptr
+type pthreadmutexattr uintptr
diff --git a/src/runtime/os_openbsd_libc.go b/src/runtime/os_openbsd_libc.go
index cff5a092d7..8150753796 100644
--- a/src/runtime/os_openbsd_libc.go
+++ b/src/runtime/os_openbsd_libc.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm64)
-// +build openbsd,386 openbsd,amd64 openbsd,arm64
+//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm) || (openbsd && arm64)
+// +build openbsd,386 openbsd,amd64 openbsd,arm openbsd,arm64
package runtime
diff --git a/src/runtime/os_openbsd_syscall.go b/src/runtime/os_openbsd_syscall.go
index 5315487961..94e851cde8 100644
--- a/src/runtime/os_openbsd_syscall.go
+++ b/src/runtime/os_openbsd_syscall.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build openbsd && !386 && openbsd && !amd64 && openbsd && !arm64
-// +build openbsd,!386,openbsd,!amd64,openbsd,!arm64
+//go:build openbsd && !386 && openbsd && !amd64 && openbsd && !arm && openbsd && !arm64
+// +build openbsd,!386,openbsd,!amd64,openbsd,!arm,openbsd,!arm64
package runtime
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index d9f8c65530..650ab6a1ee 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -1316,7 +1316,7 @@ func mStackIsSystemAllocated() bool {
return true
case "openbsd":
switch GOARCH {
- case "386", "amd64", "arm64":
+ case "386", "amd64", "arm", "arm64":
return true
}
}
diff --git a/src/runtime/sys_libc.go b/src/runtime/sys_libc.go
index 91195eb3c0..346b1ab285 100644
--- a/src/runtime/sys_libc.go
+++ b/src/runtime/sys_libc.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build darwin || (openbsd && 386) || (openbsd && amd64) || (openbsd && arm64)
-// +build darwin openbsd,386 openbsd,amd64 openbsd,arm64
+//go:build darwin || (openbsd && 386) || (openbsd && amd64) || (openbsd && arm) || (openbsd && arm64)
+// +build darwin openbsd,386 openbsd,amd64 openbsd,arm openbsd,arm64
package runtime
diff --git a/src/runtime/sys_openbsd.go b/src/runtime/sys_openbsd.go
index f6146c2e1d..89203bf85f 100644
--- a/src/runtime/sys_openbsd.go
+++ b/src/runtime/sys_openbsd.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm64)
-// +build openbsd,386 openbsd,amd64 openbsd,arm64
+//go:build (openbsd && 386) || (openbsd && amd64) || (openbsd && arm) || (openbsd && arm64)
+// +build openbsd,386 openbsd,amd64 openbsd,arm openbsd,arm64
package runtime
diff --git a/src/runtime/sys_openbsd_arm.s b/src/runtime/sys_openbsd_arm.s
index 45d69a312a..65d29415b0 100644
--- a/src/runtime/sys_openbsd_arm.s
+++ b/src/runtime/sys_openbsd_arm.s
@@ -10,7 +10,7 @@
#include "go_tls.h"
#include "textflag.h"
-#define CLOCK_REALTIME $0
+#define CLOCK_REALTIME $0
#define CLOCK_MONOTONIC $3
// With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions
@@ -25,6 +25,127 @@
NOOP; \
NOOP
+// mstart_stub is the first function executed on a new thread started by pthread_create.
+// It just does some low-level setup and then calls mstart.
+// Note: called with the C calling convention.
+TEXT runtime·mstart_stub(SB),NOSPLIT,$0
+ // R0 points to the m.
+ // We are already on m's g0 stack.
+
+ // Save callee-save registers.
+ MOVM.DB.W [R4-R11], (R13)
+
+ MOVW m_g0(R0), g
+ BL runtime·save_g(SB)
+
+ BL runtime·mstart(SB)
+
+ // Restore callee-save registers.
+ MOVM.IA.W (R13), [R4-R11]
+
+ // Go is all done with this OS thread.
+ // Tell pthread everything is ok (we never join with this thread, so
+ // the value here doesn't really matter).
+ MOVW $0, R0
+ RET
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
+ MOVW sig+4(FP), R0
+ MOVW info+8(FP), R1
+ MOVW ctx+12(FP), R2
+ MOVW fn+0(FP), R3
+ MOVW R13, R9
+ SUB $24, R13
+ BIC $0x7, R13 // alignment for ELF ABI
+ BL (R3)
+ MOVW R9, R13
+ RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+ // Reserve space for callee-save registers and arguments.
+ MOVM.DB.W [R4-R11], (R13)
+ SUB $16, R13
+
+ // If called from an external code context, g will not be set.
+ // Save R0, since runtime·load_g will clobber it.
+ MOVW R0, 4(R13) // signum
+ BL runtime·load_g(SB)
+
+ MOVW R1, 8(R13)
+ MOVW R2, 12(R13)
+ BL runtime·sigtrampgo(SB)
+
+ // Restore callee-save registers.
+ ADD $16, R13
+ MOVM.IA.W (R13), [R4-R11]
+
+ RET
+
+TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
+ B runtime·armPublicationBarrier(SB)
+
+// TODO(jsing): OpenBSD only supports GOARM=7 machines... this
+// should not be needed, however the linker still allows GOARM=5
+// on this platform.
+TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
+ MOVM.WP [R1, R2, R3, R12], (R13)
+ MOVW $330, R12 // sys___get_tcb
+ INVOKE_SYSCALL
+ MOVM.IAW (R13), [R1, R2, R3, R12]
+ RET
+
+// These trampolines help convert from Go calling convention to C calling convention.
+// They should be called with asmcgocall - note that while asmcgocall does
+// stack alignment, creation of a frame undoes it again.
+// A pointer to the arguments is passed in R0.
+// A single int32 result is returned in R0.
+// (For more results, make an args/results structure.)
+TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
+ MOVW R13, R9
+ BIC $0x7, R13 // align for ELF ABI
+ MOVW 0(R0), R0 // arg 1 attr
+ BL libc_pthread_attr_init(SB)
+ MOVW R9, R13
+ RET
+
+TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
+ MOVW R13, R9
+ BIC $0x7, R13 // align for ELF ABI
+ MOVW 0(R0), R0 // arg 1 attr
+ BL libc_pthread_attr_destroy(SB)
+ MOVW R9, R13
+ RET
+
+TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
+ MOVW R13, R9
+ BIC $0x7, R13 // align for ELF ABI
+ MOVW 4(R0), R1 // arg 2 size
+ MOVW 0(R0), R0 // arg 1 attr
+ BL libc_pthread_attr_getstacksize(SB)
+ MOVW R9, R13
+ RET
+
+TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
+ MOVW R13, R9
+ BIC $0x7, R13 // align for ELF ABI
+ MOVW 4(R0), R1 // arg 2 state
+ MOVW 0(R0), R0 // arg 1 attr
+ BL libc_pthread_attr_setdetachstate(SB)
+ MOVW R9, R13
+ RET
+
+TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
+ MOVW R13, R9
+ SUB $16, R13
+ BIC $0x7, R13 // align for ELF ABI
+ MOVW 0(R0), R1 // arg 2 attr
+ MOVW 4(R0), R2 // arg 3 start
+ MOVW 8(R0), R3 // arg 4 arg
+ MOVW R13, R0 // arg 1 &threadid (discarded)
+ BL libc_pthread_create(SB)
+ MOVW R9, R13
+ RET
+
// Exit the entire program (like C exit)
TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
MOVW code+0(FP), R0 // arg 1 - status
@@ -247,80 +368,6 @@ TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
MOVW R0, ret+8(FP)
RET
-TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
- MOVW sig+4(FP), R0
- MOVW info+8(FP), R1
- MOVW ctx+12(FP), R2
- MOVW fn+0(FP), R11
- MOVW R13, R4
- SUB $24, R13
- BIC $0x7, R13 // alignment for ELF ABI
- BL (R11)
- MOVW R4, R13
- RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$0
- // Reserve space for callee-save registers and arguments.
- MOVM.DB.W [R4-R11], (R13)
- SUB $16, R13
-
- // If called from an external code context, g will not be set.
- // Save R0, since runtime·load_g will clobber it.
- MOVW R0, 4(R13) // signum
- MOVB runtime·iscgo(SB), R0
- CMP $0, R0
- BL.NE runtime·load_g(SB)
-
- MOVW R1, 8(R13)
- MOVW R2, 12(R13)
- BL runtime·sigtrampgo(SB)
-
- // Restore callee-save registers.
- ADD $16, R13
- MOVM.IA.W (R13), [R4-R11]
-
- RET
-
-// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·tfork(SB),NOSPLIT,$0
-
- // Copy mp, gp and fn off parent stack for use by child.
- MOVW mm+8(FP), R4
- MOVW gg+12(FP), R5
- MOVW fn+16(FP), R6
-
- MOVW param+0(FP), R0 // arg 1 - param
- MOVW psize+4(FP), R1 // arg 2 - psize
- MOVW $8, R12 // sys___tfork
- INVOKE_SYSCALL
-
- // Return if syscall failed.
- B.CC 4(PC)
- RSB $0, R0
- MOVW R0, ret+20(FP)
- RET
-
- // In parent, return.
- CMP $0, R0
- BEQ 3(PC)
- MOVW R0, ret+20(FP)
- RET
-
- // Initialise m, g.
- MOVW R5, g
- MOVW R4, g_m(g)
-
- // Paranoia; check that stack splitting code works.
- BL runtime·emptyfunc(SB)
-
- // Call fn.
- BL (R6)
-
- // fn should never return.
- MOVW $2, R8 // crash if reached
- MOVW R8, (R8)
- RET
-
TEXT runtime·sigaltstack(SB),NOSPLIT,$0
MOVW new+0(FP), R0 // arg 1 - new sigaltstack
MOVW old+4(FP), R1 // arg 2 - old sigaltstack
@@ -423,13 +470,3 @@ TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
MOVW $92, R12
INVOKE_SYSCALL
RET
-
-TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
- B runtime·armPublicationBarrier(SB)
-
-TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
- MOVM.WP [R1, R2, R3, R12], (R13)
- MOVW $330, R12 // sys___get_tcb
- INVOKE_SYSCALL
- MOVM.IAW (R13), [R1, R2, R3, R12]
- RET