diff --git a/src/runtime/defs_freebsd_386.go b/src/runtime/defs_freebsd_386.go index 6294fc32d4..767755425c 100644 --- a/src/runtime/defs_freebsd_386.go +++ b/src/runtime/defs_freebsd_386.go @@ -126,6 +126,8 @@ type thrparam struct { spare [3]uintptr } +type thread int32 // long + type sigset struct { __bits [4]uint32 } diff --git a/src/runtime/defs_freebsd_amd64.go b/src/runtime/defs_freebsd_amd64.go index 840c710eeb..5a833426fd 100644 --- a/src/runtime/defs_freebsd_amd64.go +++ b/src/runtime/defs_freebsd_amd64.go @@ -127,6 +127,8 @@ type thrparam struct { spare [3]uintptr } +type thread int64 // long + type sigset struct { __bits [4]uint32 } diff --git a/src/runtime/defs_freebsd_arm.go b/src/runtime/defs_freebsd_arm.go index 3307c8bbae..b55dfd88cf 100644 --- a/src/runtime/defs_freebsd_arm.go +++ b/src/runtime/defs_freebsd_arm.go @@ -126,6 +126,8 @@ type thrparam struct { spare [3]uintptr } +type thread int32 // long + type sigset struct { __bits [4]uint32 } diff --git a/src/runtime/defs_freebsd_arm64.go b/src/runtime/defs_freebsd_arm64.go index 3eebe5dbb3..5b9d504ba6 100644 --- a/src/runtime/defs_freebsd_arm64.go +++ b/src/runtime/defs_freebsd_arm64.go @@ -127,6 +127,8 @@ type thrparam struct { spare [3]uintptr } +type thread int64 // long + type sigset struct { __bits [4]uint32 } diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go index 3266b2623a..6578fcbeb1 100644 --- a/src/runtime/os_dragonfly.go +++ b/src/runtime/os_dragonfly.go @@ -38,9 +38,11 @@ func setitimer(mode int32, new, old *itimerval) //go:noescape func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 -func raise(sig uint32) func raiseproc(sig uint32) +func lwp_gettid() int32 +func lwp_kill(pid, tid int32, sig int) + //go:noescape func sys_umtx_sleep(addr *uint32, val, timeout int32) int32 @@ -151,7 +153,7 @@ func newosproc(mp *m) { start_func: funcPC(lwp_start), arg: unsafe.Pointer(mp), stack: uintptr(stk), - tid1: unsafe.Pointer(&mp.procid), + tid1: nil, // minit will record tid tid2: nil, } @@ -191,10 +193,7 @@ func mpreinit(mp *m) { // Called to initialize a new m (including the bootstrap m). // Called on the new thread, cannot allocate memory. func minit() { - // m.procid is a uint64, but lwp_start writes an int32. Fix it up. - _g_ := getg() - _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid))) - + getg().m.procid = uint64(lwp_gettid()) minitSignals() } @@ -288,3 +287,17 @@ func sysauxv(auxv []uintptr) { } } } + +// raise sends a signal to the calling thread. +// +// It must be nosplit because it is used by the signal handler before +// it definitely has a Go stack. +// +//go:nosplit +func raise(sig uint32) { + lwp_kill(-1, lwp_gettid(), int(sig)) +} + +func signalM(mp *m, sig int) { + lwp_kill(-1, int32(mp.procid), sig) +} diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go index 183d8ab9c7..69e05b66a2 100644 --- a/src/runtime/os_freebsd.go +++ b/src/runtime/os_freebsd.go @@ -26,9 +26,11 @@ func setitimer(mode int32, new, old *itimerval) //go:noescape func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 -func raise(sig uint32) func raiseproc(sig uint32) +func thr_self() thread +func thr_kill(tid thread, sig int) + //go:noescape func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_time) int32 @@ -195,7 +197,7 @@ func newosproc(mp *m) { arg: unsafe.Pointer(mp), stack_base: mp.g0.stack.lo, stack_size: uintptr(stk) - mp.g0.stack.lo, - child_tid: unsafe.Pointer(&mp.procid), + child_tid: nil, // minit will record tid parent_tid: nil, tls_base: unsafe.Pointer(&mp.tls[0]), tls_size: unsafe.Sizeof(mp.tls), @@ -231,7 +233,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) { arg: nil, stack_base: uintptr(stack), //+stacksize? stack_size: stacksize, - child_tid: unsafe.Pointer(&m0.procid), + child_tid: nil, // minit will record tid parent_tid: nil, tls_base: unsafe.Pointer(&m0.tls[0]), tls_size: unsafe.Sizeof(m0.tls), @@ -290,12 +292,7 @@ func mpreinit(mp *m) { // Called to initialize a new m (including the bootstrap m). // Called on the new thread, cannot allocate memory. func minit() { - // m.procid is a uint64, but thr_new writes a uint32 on 32-bit systems. - // Fix it up. (Only matters on big-endian, but be clean anyway.) - if sys.PtrSize == 4 { - _g_ := getg() - _g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid))) - } + getg().m.procid = uint64(thr_self()) // On FreeBSD before about April 2017 there was a bug such // that calling execve from a thread other than the main @@ -423,3 +420,17 @@ func sysSigaction(sig uint32, new, old *sigactiont) { // asmSigaction is implemented in assembly. //go:noescape func asmSigaction(sig uintptr, new, old *sigactiont) int32 + +// raise sends a signal to the calling thread. +// +// It must be nosplit because it is used by the signal handler before +// it definitely has a Go stack. +// +//go:nosplit +func raise(sig uint32) { + thr_kill(thr_self(), int(sig)) +} + +func signalM(mp *m, sig int) { + thr_kill(thread(mp.procid), sig) +} diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go index 3cb9411a9c..b50cf237fb 100644 --- a/src/runtime/os_netbsd.go +++ b/src/runtime/os_netbsd.go @@ -47,9 +47,10 @@ func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, nds func lwp_tramp() -func raise(sig uint32) func raiseproc(sig uint32) +func lwp_kill(tid int32, sig int) + //go:noescape func getcontext(ctxt unsafe.Pointer) @@ -361,3 +362,17 @@ func sysauxv(auxv []uintptr) { } } } + +// raise sends signal to the calling thread. +// +// It must be nosplit because it is used by the signal handler before +// it definitely has a Go stack. +// +//go:nosplit +func raise(sig uint32) { + lwp_kill(lwp_self(), int(sig)) +} + +func signalM(mp *m, sig int) { + lwp_kill(int32(mp.procid), sig) +} diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go index 351a99f7e9..f26b39575d 100644 --- a/src/runtime/os_openbsd.go +++ b/src/runtime/os_openbsd.go @@ -42,9 +42,11 @@ func sigprocmask(how int32, new, old *sigset) { //go:noescape func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 -func raise(sig uint32) func raiseproc(sig uint32) +func getthrid() int32 +func thrkill(tid int32, sig int) + //go:noescape func tfork(param *tforkt, psize uintptr, mm *m, gg *g, fn uintptr) int32 @@ -190,7 +192,7 @@ func newosproc(mp *m) { // rather than at the top of it. param := tforkt{ tf_tcb: unsafe.Pointer(&mp.tls[0]), - tf_tid: (*int32)(unsafe.Pointer(&mp.procid)), + tf_tid: nil, // minit will record tid tf_stack: uintptr(stk) - sys.PtrSize, } @@ -238,10 +240,7 @@ func mpreinit(mp *m) { // Called to initialize a new m (including the bootstrap m). // Called on the new thread, can not allocate memory. func minit() { - // m.procid is a uint64, but tfork writes an int32. Fix it up. - _g_ := getg() - _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid))) - + getg().m.procid = uint64(getthrid()) minitSignals() } @@ -337,3 +336,11 @@ func osStackRemap(s *mspan, flags int32) { throw("remapping stack memory failed") } } + +func raise(sig uint32) { + thrkill(getthrid(), int(sig)) +} + +func signalM(mp *m, sig int) { + thrkill(int32(mp.procid), sig) +} diff --git a/src/runtime/sys_dragonfly_amd64.s b/src/runtime/sys_dragonfly_amd64.s index 68962d9e30..580633af55 100644 --- a/src/runtime/sys_dragonfly_amd64.s +++ b/src/runtime/sys_dragonfly_amd64.s @@ -134,12 +134,16 @@ TEXT runtime·write1(SB),NOSPLIT,$-8 MOVL AX, ret+24(FP) RET -TEXT runtime·raise(SB),NOSPLIT,$16 +TEXT runtime·lwp_gettid(SB),NOSPLIT,$0-4 MOVL $496, AX // lwp_gettid SYSCALL - MOVQ $-1, DI // arg 1 - pid - MOVQ AX, SI // arg 2 - tid - MOVL sig+0(FP), DX // arg 3 - signum + MOVL AX, ret+0(FP) + RET + +TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16 + MOVL pid+0(FP), DI // arg 1 - pid + MOVL tid+4(FP), SI // arg 2 - tid + MOVQ sig+8(FP), DX // arg 3 - signum MOVL $497, AX // lwp_kill SYSCALL RET diff --git a/src/runtime/sys_freebsd_386.s b/src/runtime/sys_freebsd_386.s index 48f64b9f8b..c346e719e1 100644 --- a/src/runtime/sys_freebsd_386.s +++ b/src/runtime/sys_freebsd_386.s @@ -131,17 +131,16 @@ TEXT runtime·write1(SB),NOSPLIT,$-4 MOVL AX, ret+12(FP) RET -TEXT runtime·raise(SB),NOSPLIT,$16 - // thr_self(&8(SP)) - LEAL 8(SP), AX +TEXT runtime·thr_self(SB),NOSPLIT,$8-4 + // thr_self(&0(FP)) + LEAL ret+0(FP), AX MOVL AX, 4(SP) MOVL $432, AX INT $0x80 - // thr_kill(self, SIGPIPE) - MOVL 8(SP), AX - MOVL AX, 4(SP) - MOVL sig+0(FP), AX - MOVL AX, 8(SP) + RET + +TEXT runtime·thr_kill(SB),NOSPLIT,$-4 + // thr_kill(tid, sig) MOVL $433, AX INT $0x80 RET diff --git a/src/runtime/sys_freebsd_amd64.s b/src/runtime/sys_freebsd_amd64.s index d24ab1f643..010b2ec4d4 100644 --- a/src/runtime/sys_freebsd_amd64.s +++ b/src/runtime/sys_freebsd_amd64.s @@ -132,14 +132,17 @@ TEXT runtime·write1(SB),NOSPLIT,$-8 MOVL AX, ret+24(FP) RET -TEXT runtime·raise(SB),NOSPLIT,$16 - // thr_self(&8(SP)) - LEAQ 8(SP), DI // arg 1 &8(SP) +TEXT runtime·thr_self(SB),NOSPLIT,$0-8 + // thr_self(&0(FP)) + LEAQ ret+0(FP), DI // arg 1 MOVL $432, AX SYSCALL - // thr_kill(self, SIGPIPE) - MOVQ 8(SP), DI // arg 1 id - MOVL sig+0(FP), SI // arg 2 + RET + +TEXT runtime·thr_kill(SB),NOSPLIT,$0-16 + // thr_kill(tid, sig) + MOVQ tid+0(FP), DI // arg 1 id + MOVQ sig+8(FP), SI // arg 2 sig MOVL $433, AX SYSCALL RET diff --git a/src/runtime/sys_freebsd_arm.s b/src/runtime/sys_freebsd_arm.s index 8da36dff17..8dcdbb56bd 100644 --- a/src/runtime/sys_freebsd_arm.s +++ b/src/runtime/sys_freebsd_arm.s @@ -165,14 +165,17 @@ TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 MOVW R0, ret+4(FP) RET -TEXT runtime·raise(SB),NOSPLIT,$8 - // thr_self(&4(R13)) - MOVW $4(R13), R0 // arg 1 &4(R13) +TEXT runtime·thr_self(SB),NOSPLIT,$0-4 + // thr_self(&0(FP)) + MOVW $ret+0(FP), R0 // arg 1 MOVW $SYS_thr_self, R7 SWI $0 - // thr_kill(self, SIGPIPE) - MOVW 4(R13), R0 // arg 1 id - MOVW sig+0(FP), R1 // arg 2 - signal + RET + +TEXT runtime·thr_kill(SB),NOSPLIT,$0-8 + // thr_kill(tid, sig) + MOVW tid+0(FP), R0 // arg 1 id + MOVW sig+4(FP), R1 // arg 2 signal MOVW $SYS_thr_kill, R7 SWI $0 RET diff --git a/src/runtime/sys_freebsd_arm64.s b/src/runtime/sys_freebsd_arm64.s index ca2ea4f1d6..e0ef2f679d 100644 --- a/src/runtime/sys_freebsd_arm64.s +++ b/src/runtime/sys_freebsd_arm64.s @@ -197,13 +197,19 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 SVC RET -// func raise(sig uint32) -TEXT runtime·raise(SB),NOSPLIT,$8 - MOVD $8(RSP), R0 // arg 1 &8(RSP) +// func thr_self() thread +TEXT runtime·thr_self(SB),NOSPLIT,$8-8 + MOVD $ptr-8(SP), R0 // arg 1 &8(SP) MOVD $SYS_thr_self, R8 SVC - MOVD 8(RSP), R0 // arg 1 pid - MOVW sig+0(FP), R1 + MOVD ptr-8(SP), R0 + MOVD R0, ret+0(FP) + RET + +// func thr_kill(t thread, sig int) +TEXT runtime·thr_kill(SB),NOSPLIT,$0-16 + MOVD tid+0(FP), R0 // arg 1 pid + MOVD sig+8(FP), R1 // arg 2 sig MOVD $SYS_thr_kill, R8 SVC RET diff --git a/src/runtime/sys_netbsd_386.s b/src/runtime/sys_netbsd_386.s index 7a542da526..d0c470c457 100644 --- a/src/runtime/sys_netbsd_386.s +++ b/src/runtime/sys_netbsd_386.s @@ -140,12 +140,11 @@ TEXT runtime·usleep(SB),NOSPLIT,$24 INT $0x80 RET -TEXT runtime·raise(SB),NOSPLIT,$12 - MOVL $SYS__lwp_self, AX - INT $0x80 +TEXT runtime·lwp_kill(SB),NOSPLIT,$12-8 MOVL $0, 0(SP) + MOVL tid+0(FP), AX MOVL AX, 4(SP) // arg 1 - target - MOVL sig+0(FP), AX + MOVL sig+4(FP), AX MOVL AX, 8(SP) // arg 2 - signo MOVL $SYS__lwp_kill, AX INT $0x80 diff --git a/src/runtime/sys_netbsd_amd64.s b/src/runtime/sys_netbsd_amd64.s index 4d1d36f01b..dc9bd127d2 100644 --- a/src/runtime/sys_netbsd_amd64.s +++ b/src/runtime/sys_netbsd_amd64.s @@ -209,11 +209,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 SYSCALL RET -TEXT runtime·raise(SB),NOSPLIT,$16 - MOVL $SYS__lwp_self, AX - SYSCALL - MOVQ AX, DI // arg 1 - target - MOVL sig+0(FP), SI // arg 2 - signo +TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16 + MOVL tid+0(FP), DI // arg 1 - target + MOVQ sig+8(FP), SI // arg 2 - signo MOVL $SYS__lwp_kill, AX SYSCALL RET diff --git a/src/runtime/sys_netbsd_arm.s b/src/runtime/sys_netbsd_arm.s index c8ee262d59..64428bee4d 100644 --- a/src/runtime/sys_netbsd_arm.s +++ b/src/runtime/sys_netbsd_arm.s @@ -193,9 +193,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 SWI $SYS___nanosleep50 RET -TEXT runtime·raise(SB),NOSPLIT,$16 - SWI $SYS__lwp_self // the returned R0 is arg 1 - MOVW sig+0(FP), R1 // arg 2 - signal +TEXT runtime·lwp_kill(SB),NOSPLIT,$0-8 + MOVW tid+0(FP), R0 // arg 1 - tid + MOVW sig+4(FP), R1 // arg 2 - signal SWI $SYS__lwp_kill RET diff --git a/src/runtime/sys_netbsd_arm64.s b/src/runtime/sys_netbsd_arm64.s index ccc34142aa..e70be0fa74 100644 --- a/src/runtime/sys_netbsd_arm64.s +++ b/src/runtime/sys_netbsd_arm64.s @@ -205,10 +205,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 SVC $SYS___nanosleep50 RET -TEXT runtime·raise(SB),NOSPLIT,$16 - SVC $SYS__lwp_self - // arg 1 - target (lwp_self) - MOVW sig+0(FP), R1 // arg 2 - signo +TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16 + MOVW tid+0(FP), R0 // arg 1 - target + MOVD sig+8(FP), R1 // arg 2 - signo SVC $SYS__lwp_kill RET diff --git a/src/runtime/sys_openbsd_386.s b/src/runtime/sys_openbsd_386.s index 9805a43802..24fbfd6266 100644 --- a/src/runtime/sys_openbsd_386.s +++ b/src/runtime/sys_openbsd_386.s @@ -97,12 +97,17 @@ TEXT runtime·usleep(SB),NOSPLIT,$24 INT $0x80 RET -TEXT runtime·raise(SB),NOSPLIT,$16 +TEXT runtime·getthrid(SB),NOSPLIT,$0-4 MOVL $299, AX // sys_getthrid INT $0x80 + MOVL AX, ret+0(FP) + RET + +TEXT runtime·thrkill(SB),NOSPLIT,$16-8 MOVL $0, 0(SP) + MOVL tid+0(FP), AX MOVL AX, 4(SP) // arg 1 - tid - MOVL sig+0(FP), AX + MOVL sig+4(FP), AX MOVL AX, 8(SP) // arg 2 - signum MOVL $0, 12(SP) // arg 3 - tcb MOVL $119, AX // sys_thrkill diff --git a/src/runtime/sys_openbsd_amd64.s b/src/runtime/sys_openbsd_amd64.s index 66526bff0d..37d70ab9aa 100644 --- a/src/runtime/sys_openbsd_amd64.s +++ b/src/runtime/sys_openbsd_amd64.s @@ -171,11 +171,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 SYSCALL RET -TEXT runtime·raise(SB),NOSPLIT,$16 +TEXT runtime·getthrid(SB),NOSPLIT,$0-4 MOVL $299, AX // sys_getthrid SYSCALL - MOVQ AX, DI // arg 1 - tid - MOVL sig+0(FP), SI // arg 2 - signum + MOVL AX, ret+0(FP) + RET + +TEXT runtime·thrkill(SB),NOSPLIT,$0-16 + MOVL tid+0(FP), DI // arg 1 - tid + MOVQ sig+8(FP), SI // arg 2 - signum MOVQ $0, DX // arg 3 - tcb MOVL $119, AX // sys_thrkill SYSCALL diff --git a/src/runtime/sys_openbsd_arm.s b/src/runtime/sys_openbsd_arm.s index 92ab3270be..2177a7308c 100644 --- a/src/runtime/sys_openbsd_arm.s +++ b/src/runtime/sys_openbsd_arm.s @@ -102,11 +102,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 SWI $0 RET -TEXT runtime·raise(SB),NOSPLIT,$12 +TEXT runtime·getthrid(SB),NOSPLIT,$0-4 MOVW $299, R12 // sys_getthrid SWI $0 - // arg 1 - tid, already in R0 - MOVW sig+0(FP), R1 // arg 2 - signum + MOVW R0, ret+0(FP) + RET + +TEXT runtime·thrkill(SB),NOSPLIT,$0-8 + MOVW tid+0(FP), R0 // arg 1 - tid + MOVW sig+4(FP), R1 // arg 2 - signum MOVW $0, R2 // arg 3 - tcb MOVW $119, R12 // sys_thrkill SWI $0 diff --git a/src/runtime/sys_openbsd_arm64.s b/src/runtime/sys_openbsd_arm64.s index c8bf2d345e..8e1a5bc542 100644 --- a/src/runtime/sys_openbsd_arm64.s +++ b/src/runtime/sys_openbsd_arm64.s @@ -114,11 +114,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 SVC RET -TEXT runtime·raise(SB),NOSPLIT,$0 +TEXT runtime·getthrid(SB),NOSPLIT,$0-4 MOVD $299, R8 // sys_getthrid SVC - // arg 1 - tid, already in R0 - MOVW sig+0(FP), R1 // arg 2 - signum + MOVW R0, ret+0(FP) + RET + +TEXT runtime·thrkill(SB),NOSPLIT,$0-16 + MOVW tid+0(FP), R0 // arg 1 - tid + MOVD sig+8(FP), R1 // arg 2 - signum MOVW $0, R2 // arg 3 - tcb MOVD $119, R8 // sys_thrkill SVC