diff options
author | Joel Sing <joel@sing.id.au> | 2021-01-31 04:21:47 +1100 |
---|---|---|
committer | Joel Sing <joel@sing.id.au> | 2021-05-09 17:05:25 +0000 |
commit | 8ec8f6aa87569a6bc567d4a7039fc22a473b37ec (patch) | |
tree | a1fe1f8e3b60aa55f98b0eb4be5ff5bf0253f4a1 | |
parent | 5203357ebacf9f41ca5e194d953c164049172e96 (diff) | |
download | go-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.s | 13 | ||||
-rw-r--r-- | src/runtime/defs_openbsd_arm.go | 9 | ||||
-rw-r--r-- | src/runtime/os_openbsd_libc.go | 4 | ||||
-rw-r--r-- | src/runtime/os_openbsd_syscall.go | 4 | ||||
-rw-r--r-- | src/runtime/proc.go | 2 | ||||
-rw-r--r-- | src/runtime/sys_libc.go | 4 | ||||
-rw-r--r-- | src/runtime/sys_openbsd.go | 4 | ||||
-rw-r--r-- | src/runtime/sys_openbsd_arm.s | 207 |
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 |