Commit 8714e394 authored by Austin Clements's avatar Austin Clements

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: default avatarCherry Zhang <cherryyz@google.com>
parent 334291d1
...@@ -126,6 +126,8 @@ type thrparam struct { ...@@ -126,6 +126,8 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type thread int32 // long
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -127,6 +127,8 @@ type thrparam struct { ...@@ -127,6 +127,8 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type thread int64 // long
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -126,6 +126,8 @@ type thrparam struct { ...@@ -126,6 +126,8 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type thread int32 // long
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -127,6 +127,8 @@ type thrparam struct { ...@@ -127,6 +127,8 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type thread int64 // long
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -38,9 +38,11 @@ func setitimer(mode int32, new, old *itimerval) ...@@ -38,9 +38,11 @@ func setitimer(mode int32, new, old *itimerval)
//go:noescape //go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
func raise(sig uint32)
func raiseproc(sig uint32) func raiseproc(sig uint32)
func lwp_gettid() int32
func lwp_kill(pid, tid int32, sig int)
//go:noescape //go:noescape
func sys_umtx_sleep(addr *uint32, val, timeout int32) int32 func sys_umtx_sleep(addr *uint32, val, timeout int32) int32
...@@ -151,7 +153,7 @@ func newosproc(mp *m) { ...@@ -151,7 +153,7 @@ func newosproc(mp *m) {
start_func: funcPC(lwp_start), start_func: funcPC(lwp_start),
arg: unsafe.Pointer(mp), arg: unsafe.Pointer(mp),
stack: uintptr(stk), stack: uintptr(stk),
tid1: unsafe.Pointer(&mp.procid), tid1: nil, // minit will record tid
tid2: nil, tid2: nil,
} }
...@@ -191,10 +193,7 @@ func mpreinit(mp *m) { ...@@ -191,10 +193,7 @@ func mpreinit(mp *m) {
// Called to initialize a new m (including the bootstrap m). // Called to initialize a new m (including the bootstrap m).
// Called on the new thread, cannot allocate memory. // Called on the new thread, cannot allocate memory.
func minit() { func minit() {
// m.procid is a uint64, but lwp_start writes an int32. Fix it up. getg().m.procid = uint64(lwp_gettid())
_g_ := getg()
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
minitSignals() minitSignals()
} }
...@@ -288,3 +287,17 @@ func sysauxv(auxv []uintptr) { ...@@ -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) ...@@ -26,9 +26,11 @@ func setitimer(mode int32, new, old *itimerval)
//go:noescape //go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
func raise(sig uint32)
func raiseproc(sig uint32) func raiseproc(sig uint32)
func thr_self() thread
func thr_kill(tid thread, sig int)
//go:noescape //go:noescape
func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_time) int32 func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_time) int32
...@@ -195,7 +197,7 @@ func newosproc(mp *m) { ...@@ -195,7 +197,7 @@ func newosproc(mp *m) {
arg: unsafe.Pointer(mp), arg: unsafe.Pointer(mp),
stack_base: mp.g0.stack.lo, stack_base: mp.g0.stack.lo,
stack_size: uintptr(stk) - 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, parent_tid: nil,
tls_base: unsafe.Pointer(&mp.tls[0]), tls_base: unsafe.Pointer(&mp.tls[0]),
tls_size: unsafe.Sizeof(mp.tls), tls_size: unsafe.Sizeof(mp.tls),
...@@ -231,7 +233,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) { ...@@ -231,7 +233,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
arg: nil, arg: nil,
stack_base: uintptr(stack), //+stacksize? stack_base: uintptr(stack), //+stacksize?
stack_size: stacksize, stack_size: stacksize,
child_tid: unsafe.Pointer(&m0.procid), child_tid: nil, // minit will record tid
parent_tid: nil, parent_tid: nil,
tls_base: unsafe.Pointer(&m0.tls[0]), tls_base: unsafe.Pointer(&m0.tls[0]),
tls_size: unsafe.Sizeof(m0.tls), tls_size: unsafe.Sizeof(m0.tls),
...@@ -290,12 +292,7 @@ func mpreinit(mp *m) { ...@@ -290,12 +292,7 @@ func mpreinit(mp *m) {
// Called to initialize a new m (including the bootstrap m). // Called to initialize a new m (including the bootstrap m).
// Called on the new thread, cannot allocate memory. // Called on the new thread, cannot allocate memory.
func minit() { func minit() {
// m.procid is a uint64, but thr_new writes a uint32 on 32-bit systems. getg().m.procid = uint64(thr_self())
// 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)))
}
// On FreeBSD before about April 2017 there was a bug such // On FreeBSD before about April 2017 there was a bug such
// that calling execve from a thread other than the main // that calling execve from a thread other than the main
...@@ -423,3 +420,17 @@ func sysSigaction(sig uint32, new, old *sigactiont) { ...@@ -423,3 +420,17 @@ func sysSigaction(sig uint32, new, old *sigactiont) {
// asmSigaction is implemented in assembly. // asmSigaction is implemented in assembly.
//go:noescape //go:noescape
func asmSigaction(sig uintptr, new, old *sigactiont) int32 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 ...@@ -47,9 +47,10 @@ func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, nds
func lwp_tramp() func lwp_tramp()
func raise(sig uint32)
func raiseproc(sig uint32) func raiseproc(sig uint32)
func lwp_kill(tid int32, sig int)
//go:noescape //go:noescape
func getcontext(ctxt unsafe.Pointer) func getcontext(ctxt unsafe.Pointer)
...@@ -361,3 +362,17 @@ func sysauxv(auxv []uintptr) { ...@@ -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) { ...@@ -42,9 +42,11 @@ func sigprocmask(how int32, new, old *sigset) {
//go:noescape //go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
func raise(sig uint32)
func raiseproc(sig uint32) func raiseproc(sig uint32)
func getthrid() int32
func thrkill(tid int32, sig int)
//go:noescape //go:noescape
func tfork(param *tforkt, psize uintptr, mm *m, gg *g, fn uintptr) int32 func tfork(param *tforkt, psize uintptr, mm *m, gg *g, fn uintptr) int32
...@@ -190,7 +192,7 @@ func newosproc(mp *m) { ...@@ -190,7 +192,7 @@ func newosproc(mp *m) {
// rather than at the top of it. // rather than at the top of it.
param := tforkt{ param := tforkt{
tf_tcb: unsafe.Pointer(&mp.tls[0]), 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, tf_stack: uintptr(stk) - sys.PtrSize,
} }
...@@ -238,10 +240,7 @@ func mpreinit(mp *m) { ...@@ -238,10 +240,7 @@ func mpreinit(mp *m) {
// Called to initialize a new m (including the bootstrap m). // Called to initialize a new m (including the bootstrap m).
// Called on the new thread, can not allocate memory. // Called on the new thread, can not allocate memory.
func minit() { func minit() {
// m.procid is a uint64, but tfork writes an int32. Fix it up. getg().m.procid = uint64(getthrid())
_g_ := getg()
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
minitSignals() minitSignals()
} }
...@@ -337,3 +336,11 @@ func osStackRemap(s *mspan, flags int32) { ...@@ -337,3 +336,11 @@ func osStackRemap(s *mspan, flags int32) {
throw("remapping stack memory failed") 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 ...@@ -134,12 +134,16 @@ TEXT runtime·write1(SB),NOSPLIT,$-8
MOVL AX, ret+24(FP) MOVL AX, ret+24(FP)
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·lwp_gettid(SB),NOSPLIT,$0-4
MOVL $496, AX // lwp_gettid MOVL $496, AX // lwp_gettid
SYSCALL SYSCALL
MOVQ $-1, DI // arg 1 - pid MOVL AX, ret+0(FP)
MOVQ AX, SI // arg 2 - tid RET
MOVL sig+0(FP), DX // arg 3 - signum
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 MOVL $497, AX // lwp_kill
SYSCALL SYSCALL
RET RET
......
...@@ -131,17 +131,16 @@ TEXT runtime·write1(SB),NOSPLIT,$-4 ...@@ -131,17 +131,16 @@ TEXT runtime·write1(SB),NOSPLIT,$-4
MOVL AX, ret+12(FP) MOVL AX, ret+12(FP)
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·thr_self(SB),NOSPLIT,$8-4
// thr_self(&8(SP)) // thr_self(&0(FP))
LEAL 8(SP), AX LEAL ret+0(FP), AX
MOVL AX, 4(SP) MOVL AX, 4(SP)
MOVL $432, AX MOVL $432, AX
INT $0x80 INT $0x80
// thr_kill(self, SIGPIPE) RET
MOVL 8(SP), AX
MOVL AX, 4(SP) TEXT runtime·thr_kill(SB),NOSPLIT,$-4
MOVL sig+0(FP), AX // thr_kill(tid, sig)
MOVL AX, 8(SP)
MOVL $433, AX MOVL $433, AX
INT $0x80 INT $0x80
RET RET
......
...@@ -132,14 +132,17 @@ TEXT runtime·write1(SB),NOSPLIT,$-8 ...@@ -132,14 +132,17 @@ TEXT runtime·write1(SB),NOSPLIT,$-8
MOVL AX, ret+24(FP) MOVL AX, ret+24(FP)
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·thr_self(SB),NOSPLIT,$0-8
// thr_self(&8(SP)) // thr_self(&0(FP))
LEAQ 8(SP), DI // arg 1 &8(SP) LEAQ ret+0(FP), DI // arg 1
MOVL $432, AX MOVL $432, AX
SYSCALL SYSCALL
// thr_kill(self, SIGPIPE) RET
MOVQ 8(SP), DI // arg 1 id
MOVL sig+0(FP), SI // arg 2 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 MOVL $433, AX
SYSCALL SYSCALL
RET RET
......
...@@ -165,14 +165,17 @@ TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 ...@@ -165,14 +165,17 @@ TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
MOVW R0, ret+4(FP) MOVW R0, ret+4(FP)
RET RET
TEXT runtime·raise(SB),NOSPLIT,$8 TEXT runtime·thr_self(SB),NOSPLIT,$0-4
// thr_self(&4(R13)) // thr_self(&0(FP))
MOVW $4(R13), R0 // arg 1 &4(R13) MOVW $ret+0(FP), R0 // arg 1
MOVW $SYS_thr_self, R7 MOVW $SYS_thr_self, R7
SWI $0 SWI $0
// thr_kill(self, SIGPIPE) RET
MOVW 4(R13), R0 // arg 1 id
MOVW sig+0(FP), R1 // arg 2 - signal 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 MOVW $SYS_thr_kill, R7
SWI $0 SWI $0
RET RET
......
...@@ -197,13 +197,19 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 ...@@ -197,13 +197,19 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4
SVC SVC
RET RET
// func raise(sig uint32) // func thr_self() thread
TEXT runtime·raise(SB),NOSPLIT,$8 TEXT runtime·thr_self(SB),NOSPLIT,$8-8
MOVD $8(RSP), R0 // arg 1 &8(RSP) MOVD $ptr-8(SP), R0 // arg 1 &8(SP)
MOVD $SYS_thr_self, R8 MOVD $SYS_thr_self, R8
SVC SVC
MOVD 8(RSP), R0 // arg 1 pid MOVD ptr-8(SP), R0
MOVW sig+0(FP), R1 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 MOVD $SYS_thr_kill, R8
SVC SVC
RET RET
......
...@@ -140,12 +140,11 @@ TEXT runtime·usleep(SB),NOSPLIT,$24 ...@@ -140,12 +140,11 @@ TEXT runtime·usleep(SB),NOSPLIT,$24
INT $0x80 INT $0x80
RET RET
TEXT runtime·raise(SB),NOSPLIT,$12 TEXT runtime·lwp_kill(SB),NOSPLIT,$12-8
MOVL $SYS__lwp_self, AX
INT $0x80
MOVL $0, 0(SP) MOVL $0, 0(SP)
MOVL tid+0(FP), AX
MOVL AX, 4(SP) // arg 1 - target 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 AX, 8(SP) // arg 2 - signo
MOVL $SYS__lwp_kill, AX MOVL $SYS__lwp_kill, AX
INT $0x80 INT $0x80
......
...@@ -209,11 +209,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 ...@@ -209,11 +209,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
SYSCALL SYSCALL
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16
MOVL $SYS__lwp_self, AX MOVL tid+0(FP), DI // arg 1 - target
SYSCALL MOVQ sig+8(FP), SI // arg 2 - signo
MOVQ AX, DI // arg 1 - target
MOVL sig+0(FP), SI // arg 2 - signo
MOVL $SYS__lwp_kill, AX MOVL $SYS__lwp_kill, AX
SYSCALL SYSCALL
RET RET
......
...@@ -193,9 +193,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 ...@@ -193,9 +193,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
SWI $SYS___nanosleep50 SWI $SYS___nanosleep50
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·lwp_kill(SB),NOSPLIT,$0-8
SWI $SYS__lwp_self // the returned R0 is arg 1 MOVW tid+0(FP), R0 // arg 1 - tid
MOVW sig+0(FP), R1 // arg 2 - signal MOVW sig+4(FP), R1 // arg 2 - signal
SWI $SYS__lwp_kill SWI $SYS__lwp_kill
RET RET
......
...@@ -205,10 +205,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 ...@@ -205,10 +205,9 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4
SVC $SYS___nanosleep50 SVC $SYS___nanosleep50
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16
SVC $SYS__lwp_self MOVW tid+0(FP), R0 // arg 1 - target
// arg 1 - target (lwp_self) MOVD sig+8(FP), R1 // arg 2 - signo
MOVW sig+0(FP), R1 // arg 2 - signo
SVC $SYS__lwp_kill SVC $SYS__lwp_kill
RET RET
......
...@@ -97,12 +97,17 @@ TEXT runtime·usleep(SB),NOSPLIT,$24 ...@@ -97,12 +97,17 @@ TEXT runtime·usleep(SB),NOSPLIT,$24
INT $0x80 INT $0x80
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·getthrid(SB),NOSPLIT,$0-4
MOVL $299, AX // sys_getthrid MOVL $299, AX // sys_getthrid
INT $0x80 INT $0x80
MOVL AX, ret+0(FP)
RET
TEXT runtime·thrkill(SB),NOSPLIT,$16-8
MOVL $0, 0(SP) MOVL $0, 0(SP)
MOVL tid+0(FP), AX
MOVL AX, 4(SP) // arg 1 - tid 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 AX, 8(SP) // arg 2 - signum
MOVL $0, 12(SP) // arg 3 - tcb MOVL $0, 12(SP) // arg 3 - tcb
MOVL $119, AX // sys_thrkill MOVL $119, AX // sys_thrkill
......
...@@ -171,11 +171,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 ...@@ -171,11 +171,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
SYSCALL SYSCALL
RET RET
TEXT runtime·raise(SB),NOSPLIT,$16 TEXT runtime·getthrid(SB),NOSPLIT,$0-4
MOVL $299, AX // sys_getthrid MOVL $299, AX // sys_getthrid
SYSCALL SYSCALL
MOVQ AX, DI // arg 1 - tid MOVL AX, ret+0(FP)
MOVL sig+0(FP), SI // arg 2 - signum 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 MOVQ $0, DX // arg 3 - tcb
MOVL $119, AX // sys_thrkill MOVL $119, AX // sys_thrkill
SYSCALL SYSCALL
......
...@@ -102,11 +102,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 ...@@ -102,11 +102,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
SWI $0 SWI $0
RET RET
TEXT runtime·raise(SB),NOSPLIT,$12 TEXT runtime·getthrid(SB),NOSPLIT,$0-4
MOVW $299, R12 // sys_getthrid MOVW $299, R12 // sys_getthrid
SWI $0 SWI $0
// arg 1 - tid, already in R0 MOVW R0, ret+0(FP)
MOVW sig+0(FP), R1 // arg 2 - signum 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 $0, R2 // arg 3 - tcb
MOVW $119, R12 // sys_thrkill MOVW $119, R12 // sys_thrkill
SWI $0 SWI $0
......
...@@ -114,11 +114,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4 ...@@ -114,11 +114,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$24-4
SVC SVC
RET RET
TEXT runtime·raise(SB),NOSPLIT,$0 TEXT runtime·getthrid(SB),NOSPLIT,$0-4
MOVD $299, R8 // sys_getthrid MOVD $299, R8 // sys_getthrid
SVC SVC
// arg 1 - tid, already in R0 MOVW R0, ret+0(FP)
MOVW sig+0(FP), R1 // arg 2 - signum 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 MOVW $0, R2 // arg 3 - tcb
MOVD $119, R8 // sys_thrkill MOVD $119, R8 // sys_thrkill
SVC SVC
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment