mirror of
https://github.com/golang/go
synced 2024-11-23 11:50:09 -07:00
runtime: M-targeted signals for BSDs
For these, we split up the existing runtime.raise assembly implementation into its constituent "get thread ID" and "signal thread" parts. This lets us implement signalM and reimplement raise in pure Go. (NetBSD conveniently already had lwp_self.) We also change minit to store the procid directly, rather than depending on newosproc to do so. This is because newosproc isn't called for the bootstrap M, but we need a procid for every M. This is also simpler overall. For #10958, #24543. Change-Id: Ie5f1fcada6a33046375066bcbe054d1f784d39c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/201402 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
334291d1f6
commit
8714e39497
@ -126,6 +126,8 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type thread int32 // long
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type thread int64 // long
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -126,6 +126,8 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type thread int32 // long
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type thread int64 // long
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user