mirror of
https://github.com/golang/go
synced 2024-09-30 04:24:29 -06:00
runtime: use a proper type, sigset, for m.sigmask
Replace the cross platform but unsafe [4]uintptr type with a OS specific type, sigset. Most OSes already define sigset, and this change defines a suitable sigset for the OSes that don't (darwin, openbsd). The OSes that don't use m.sigmask (windows, plan9, nacl) now defines sigset as the empty type, struct{}. The gain is strongly typed access to m.sigmask, saving a dynamic size sanity check and unsafe.Pointer casting. Also, some storage is saved for each M, since [4]uinptr was conservative for most OSes. The cost is that OSes that don't need m.sigmask has to define sigset. completes ./all.bash with GOOS linux, on amd64 completes ./make.bash with GOOSes openbsd, android, plan9, windows, darwin, solaris, netbsd, freebsd, dragonfly, all amd64. With GOOS=nacl ./make.bash failed with a seemingly unrelated error. R=go1.7 Change-Id: Ib460379f063eb83d393e1c5efe7333a643c1595e Reviewed-on: https://go-review.googlesource.com/16942 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
07d48993f2
commit
7db77271e4
@ -8,7 +8,9 @@ import "unsafe"
|
||||
|
||||
//extern SigTabTT runtime·sigtab[];
|
||||
|
||||
var sigset_all = ^uint32(0)
|
||||
type sigset uint32
|
||||
|
||||
var sigset_all = ^sigset(0)
|
||||
|
||||
func unimplemented(name string) {
|
||||
println(name, "not implemented")
|
||||
@ -83,7 +85,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
|
||||
print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
|
||||
}
|
||||
|
||||
var oset uint32
|
||||
var oset sigset
|
||||
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
|
||||
errno := bsdthread_create(stk, unsafe.Pointer(mp), funcPC(mstart))
|
||||
sigprocmask(_SIG_SETMASK, &oset, nil)
|
||||
@ -109,7 +111,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) {
|
||||
}
|
||||
stk := unsafe.Pointer(uintptr(stack) + stacksize)
|
||||
|
||||
var oset uint32
|
||||
var oset sigset
|
||||
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
|
||||
errno := bsdthread_create(stk, fn, fnarg)
|
||||
sigprocmask(_SIG_SETMASK, &oset, nil)
|
||||
@ -131,11 +133,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -146,7 +144,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask &^= 1 << (uint32(i) - 1)
|
||||
@ -158,8 +156,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*uint32)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
|
||||
signalstack(nil)
|
||||
}
|
||||
|
||||
@ -472,10 +469,11 @@ func signalstack(s *stack) {
|
||||
}
|
||||
|
||||
func updatesigmask(m sigmask) {
|
||||
sigprocmask(_SIG_SETMASK, &m[0], nil)
|
||||
s := sigset(m[0])
|
||||
sigprocmask(_SIG_SETMASK, &s, nil)
|
||||
}
|
||||
|
||||
func unblocksig(sig int32) {
|
||||
mask := uint32(1) << (uint32(sig) - 1)
|
||||
mask := sigset(1) << (uint32(sig) - 1)
|
||||
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||
}
|
||||
|
@ -118,11 +118,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -137,7 +133,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||
@ -149,8 +145,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
|
||||
signalstack(nil)
|
||||
}
|
||||
|
||||
|
@ -121,11 +121,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -143,7 +139,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||
@ -155,8 +151,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
|
||||
signalstack(nil)
|
||||
}
|
||||
|
||||
|
@ -198,10 +198,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
smask := &mp.sigmask
|
||||
rtsigprocmask(_SIG_SETMASK, nil, smask, int32(unsafe.Sizeof(*smask)))
|
||||
}
|
||||
|
||||
@ -218,7 +215,7 @@ func minit() {
|
||||
_g_.m.procid = uint64(gettid())
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
sigdelset(&nmask, i)
|
||||
@ -230,7 +227,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
smask := &_g_.m.sigmask
|
||||
rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask)))
|
||||
signalstack(nil)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type sigset struct{}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
||||
func mpreinit(mp *m) {
|
||||
|
@ -139,11 +139,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -156,7 +152,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||
@ -168,8 +164,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
|
||||
|
||||
signalstack(nil)
|
||||
}
|
||||
|
@ -22,9 +22,11 @@ const (
|
||||
_CLOCK_MONOTONIC = 3
|
||||
)
|
||||
|
||||
type sigset uint32
|
||||
|
||||
const (
|
||||
sigset_none = uint32(0)
|
||||
sigset_all = ^uint32(0)
|
||||
sigset_none = sigset(0)
|
||||
sigset_all = ^sigset(0)
|
||||
)
|
||||
|
||||
// From OpenBSD's <sys/sysctl.h>
|
||||
@ -149,11 +151,7 @@ func mpreinit(mp *m) {
|
||||
}
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*uint32)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
*smask = sigprocmask(_SIG_BLOCK, 0)
|
||||
mp.sigmask = sigprocmask(_SIG_BLOCK, 0)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -168,7 +166,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask &^= 1 << (uint32(i) - 1)
|
||||
@ -180,8 +178,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := *(*uint32)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask)
|
||||
sigprocmask(_SIG_SETMASK, _g_.m.sigmask)
|
||||
signalstack(nil)
|
||||
}
|
||||
|
||||
@ -203,7 +200,7 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
if restart {
|
||||
sa.sa_flags |= _SA_RESTART
|
||||
}
|
||||
sa.sa_mask = sigset_all
|
||||
sa.sa_mask = uint32(sigset_all)
|
||||
if fn == funcPC(sighandler) {
|
||||
fn = funcPC(sigtramp)
|
||||
}
|
||||
@ -237,10 +234,10 @@ func signalstack(s *stack) {
|
||||
}
|
||||
|
||||
func updatesigmask(m sigmask) {
|
||||
sigprocmask(_SIG_SETMASK, m[0])
|
||||
sigprocmask(_SIG_SETMASK, sigset(m[0]))
|
||||
}
|
||||
|
||||
func unblocksig(sig int32) {
|
||||
mask := uint32(1) << (uint32(sig) - 1)
|
||||
mask := sigset(1) << (uint32(sig) - 1)
|
||||
sigprocmask(_SIG_UNBLOCK, mask)
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type sigset struct{}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
||||
func mpreinit(mp *m) {
|
||||
|
@ -99,6 +99,8 @@ var (
|
||||
_GetQueuedCompletionStatusEx stdFunction
|
||||
)
|
||||
|
||||
type sigset struct{}
|
||||
|
||||
// Call a Windows function with stdcall conventions,
|
||||
// and switch to os stack during the call.
|
||||
func asmstdcall(fn unsafe.Pointer)
|
||||
|
@ -193,11 +193,7 @@ func mpreinit(mp *m) {
|
||||
func miniterrno()
|
||||
|
||||
func msigsave(mp *m) {
|
||||
smask := (*sigset)(unsafe.Pointer(&mp.sigmask))
|
||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||
throw("insufficient storage for signal mask")
|
||||
}
|
||||
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||
sigprocmask(_SIG_SETMASK, nil, &mp.sigmask)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
@ -209,7 +205,7 @@ func minit() {
|
||||
signalstack(&_g_.m.gsignal.stack)
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
nmask := _g_.m.sigmask
|
||||
for i := range sigtable {
|
||||
if sigtable[i].flags&_SigUnblock != 0 {
|
||||
nmask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||
@ -221,8 +217,7 @@ func minit() {
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
_g_ := getg()
|
||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||
sigprocmask(_SIG_SETMASK, &_g_.m.sigmask, nil)
|
||||
|
||||
signalstack(nil)
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ func mach_thread_self() uint32
|
||||
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
|
||||
|
||||
//go:noescape
|
||||
func sigprocmask(how uint32, new, old *uint32)
|
||||
func sigprocmask(how uint32, new, old *sigset)
|
||||
|
||||
//go:noescape
|
||||
func sigaction(mode uint32, new, old *sigactiont)
|
||||
|
@ -18,7 +18,7 @@ func sigaction(sig int32, new, old *sigactiont)
|
||||
func sigaltstack(new, old *stackt)
|
||||
|
||||
//go:noescape
|
||||
func sigprocmask(mode int32, new uint32) uint32
|
||||
func sigprocmask(mode int32, new sigset) sigset
|
||||
|
||||
//go:noescape
|
||||
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
|
||||
|
@ -273,7 +273,7 @@ type m struct {
|
||||
// Fields not known to debuggers.
|
||||
procid uint64 // for debuggers, but offset not hard-coded
|
||||
gsignal *g // signal-handling g
|
||||
sigmask [4]uintptr // storage for saved signal mask
|
||||
sigmask sigset // storage for saved signal mask
|
||||
tls [6]uintptr // thread-local storage (for x86 extern register)
|
||||
mstartfn func()
|
||||
curg *g // current running goroutine
|
||||
|
Loading…
Reference in New Issue
Block a user