]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: M-targeted signals for BSDs
authorAustin Clements <austin@google.com>
Mon, 14 Oct 2019 21:05:56 +0000 (17:05 -0400)
committerAustin Clements <austin@google.com>
Sat, 26 Oct 2019 02:52:28 +0000 (02:52 +0000)
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>
21 files changed:
src/runtime/defs_freebsd_386.go
src/runtime/defs_freebsd_amd64.go
src/runtime/defs_freebsd_arm.go
src/runtime/defs_freebsd_arm64.go
src/runtime/os_dragonfly.go
src/runtime/os_freebsd.go
src/runtime/os_netbsd.go
src/runtime/os_openbsd.go
src/runtime/sys_dragonfly_amd64.s
src/runtime/sys_freebsd_386.s
src/runtime/sys_freebsd_amd64.s
src/runtime/sys_freebsd_arm.s
src/runtime/sys_freebsd_arm64.s
src/runtime/sys_netbsd_386.s
src/runtime/sys_netbsd_amd64.s
src/runtime/sys_netbsd_arm.s
src/runtime/sys_netbsd_arm64.s
src/runtime/sys_openbsd_386.s
src/runtime/sys_openbsd_amd64.s
src/runtime/sys_openbsd_arm.s
src/runtime/sys_openbsd_arm64.s

index 6294fc32d4ccb96029dcb8a9c685388f0b435045..767755425c125d8c9bcca51a5122449d30230d19 100644 (file)
@@ -126,6 +126,8 @@ type thrparam struct {
        spare      [3]uintptr
 }
 
+type thread int32 // long
+
 type sigset struct {
        __bits [4]uint32
 }
index 840c710eeb966388bc59744d6606b89e0264d98d..5a833426fd68e49e2a8087d29ad04aef53c51479 100644 (file)
@@ -127,6 +127,8 @@ type thrparam struct {
        spare      [3]uintptr
 }
 
+type thread int64 // long
+
 type sigset struct {
        __bits [4]uint32
 }
index 3307c8bbae3aa3c67c8030c28f39bebb670376de..b55dfd88cf2e36cc0c630c4d0b59e6d9421de52d 100644 (file)
@@ -126,6 +126,8 @@ type thrparam struct {
        spare      [3]uintptr
 }
 
+type thread int32 // long
+
 type sigset struct {
        __bits [4]uint32
 }
index 3eebe5dbb3dd33ad984e668fcd1470aa0c186ca8..5b9d504ba6f990a15285f1248e8c4e78d67fa717 100644 (file)
@@ -127,6 +127,8 @@ type thrparam struct {
        spare      [3]uintptr
 }
 
+type thread int64 // long
+
 type sigset struct {
        __bits [4]uint32
 }
index 3266b2623a5eecffd19a94a7f8d2ae946767f71b..6578fcbeb1f331f75b2ee15e9ed4907c77b3411e 100644 (file)
@@ -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)
+}
index 183d8ab9c7c72f4ed84367e05749ea5184a2e50a..69e05b66a2842a531a2327056bed87afaa183c72 100644 (file)
@@ -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)
+}
index 3cb9411a9cd80d9a1e3c37678866f7c4f927fab7..b50cf237fb920e91c97b91a71ff1ef99a5d9c480 100644 (file)
@@ -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)
+}
index 351a99f7e9f61cd0c2d2af186fb488fa1a9fbd3e..f26b39575d37e0a84cb635684372dd432b510db9 100644 (file)
@@ -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)
+}
index 68962d9e3054bb31837c685053feda65c7b0eee1..580633af559b80a42dac8543708b74e49174115a 100644 (file)
@@ -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
index 48f64b9f8b6f28d9a356e9c13db145206c0f1010..c346e719e14fe25fb8f106a8d678a652f40e0ad7 100644 (file)
@@ -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
index d24ab1f643c27dc9aad355c4f85bb634e91d3cf0..010b2ec4d4dc2c82f1b923b1068a762c77da36f1 100644 (file)
@@ -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
index 8da36dff178615c0836649c0157867e2a3e07bf7..8dcdbb56bdb70ac55c84a3bec9830d933f375bf7 100644 (file)
@@ -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
index ca2ea4f1d6c5f13576417d9046d2f9d9ce7f8d43..e0ef2f679de4a697d0886d2334e8ccdcf022263c 100644 (file)
@@ -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
index 7a542da526b22feb2039c780797c56aeb3de061a..d0c470c4575cc8fe9a540467775aa7357d7caa1b 100644 (file)
@@ -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
index 4d1d36f01bfa53ddbe6b471212181b09f0a7133b..dc9bd127d2349d0dc0f5d79a99e2e90946569aca 100644 (file)
@@ -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
index c8ee262d59b49d6ce5385e48d1844b8a12ea968a..64428bee4db002cfb8aba54085d84214ce10f240 100644 (file)
@@ -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
 
index ccc34142aa34c87a6aefe809e6b6c5bb4e8492d4..e70be0fa743a285c5fcd62121ac2846a716b57e3 100644 (file)
@@ -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
 
index 9805a438025c6bc33255e166f896dcca77f1a5ef..24fbfd6266e1961a071b927667a0714e6811f227 100644 (file)
@@ -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
index 66526bff0de84c30cdb62a09a49b2f712cab60cb..37d70ab9aa2d9131ea3cecd7f233a19cb486faf6 100644 (file)
@@ -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
index 92ab3270beecee62785b58ee16e3c40df6ba35c0..2177a7308c3326083c5ec979af25a7b476aad475 100644 (file)
@@ -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
index c8bf2d345e57068b03cecf35a7d1001c19b38f14..8e1a5bc5424a30c472b39a31bd2848c93bbace6d 100644 (file)
@@ -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