Commit ac24388e authored by Ian Lance Taylor's avatar Ian Lance Taylor

runtime: merge setting new signal mask in minit

All the variants that sets the new signal mask in minit do the same
thing, so merge them. This requires an OS-specific sigdelset function;
the function already exists for linux, and is now added for other OS's.

Change-Id: Ie96f6f02e2cf09c43005085985a078bd9581f670
Reviewed-on: https://go-review.googlesource.com/29771
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 33902943
...@@ -207,19 +207,9 @@ func miniterrno() ...@@ -207,19 +207,9 @@ func miniterrno()
// 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() {
_g_ := getg()
asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno)) asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno))
minitSignalStack() minitSignals()
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -318,6 +308,10 @@ func sigmaskToSigset(m sigmask) sigset { ...@@ -318,6 +308,10 @@ func sigmaskToSigset(m sigmask) sigset {
return set return set
} }
func sigdelset(mask *sigset, i int) {
mask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
func (c *sigctxt) fixsigcode(sig uint32) { func (c *sigctxt) fixsigcode(sig uint32) {
} }
......
...@@ -176,24 +176,13 @@ func mpreinit(mp *m) { ...@@ -176,24 +176,13 @@ 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() {
// Initialize signal handling.
_g_ := getg()
// The alternate signal stack is buggy on arm and arm64. // The alternate signal stack is buggy on arm and arm64.
// The signal handler handles it directly. // The signal handler handles it directly.
// The sigaltstack assembly function does nothing. // The sigaltstack assembly function does nothing.
if GOARCH != "arm" && GOARCH != "arm64" { if GOARCH != "arm" && GOARCH != "arm64" {
minitSignalStack() minitSignalStack()
} }
minitSignalMask()
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask &^= 1 << (uint32(i) - 1)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -560,3 +549,7 @@ func setSignalstackSP(s *stackt, sp uintptr) { ...@@ -560,3 +549,7 @@ func setSignalstackSP(s *stackt, sp uintptr) {
func sigmaskToSigset(m sigmask) sigset { func sigmaskToSigset(m sigmask) sigset {
return sigset(m[0]) return sigset(m[0])
} }
func sigdelset(mask *sigset, i int) {
*mask &^= 1 << (uint32(i) - 1)
}
...@@ -180,21 +180,11 @@ func mpreinit(mp *m) { ...@@ -180,21 +180,11 @@ 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() {
_g_ := getg()
// m.procid is a uint64, but lwp_start writes an int32. Fix it up. // 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))) _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
minitSignalStack() minitSignals()
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -291,5 +281,9 @@ func sigmaskToSigset(m sigmask) sigset { ...@@ -291,5 +281,9 @@ func sigmaskToSigset(m sigmask) sigset {
return set return set
} }
func sigdelset(mask *sigset, i int) {
mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
func (c *sigctxt) fixsigcode(sig uint32) { func (c *sigctxt) fixsigcode(sig uint32) {
} }
...@@ -167,24 +167,14 @@ func mpreinit(mp *m) { ...@@ -167,24 +167,14 @@ 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() {
_g_ := getg()
// m.procid is a uint64, but thr_new writes a uint32 on 32-bit systems. // 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.) // Fix it up. (Only matters on big-endian, but be clean anyway.)
if sys.PtrSize == 4 { if sys.PtrSize == 4 {
_g_ := getg()
_g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid))) _g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid)))
} }
minitSignalStack() minitSignals()
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -281,5 +271,9 @@ func sigmaskToSigset(m sigmask) sigset { ...@@ -281,5 +271,9 @@ func sigmaskToSigset(m sigmask) sigset {
return set return set
} }
func sigdelset(mask *sigset, i int) {
mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
func (c *sigctxt) fixsigcode(sig uint32) { func (c *sigctxt) fixsigcode(sig uint32) {
} }
...@@ -257,22 +257,10 @@ func gettid() uint32 ...@@ -257,22 +257,10 @@ func gettid() uint32
// 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() {
// Initialize signal handling. minitSignals()
_g_ := getg()
minitSignalStack()
// for debuggers, in case cgo created the thread // for debuggers, in case cgo created the thread
_g_.m.procid = uint64(gettid()) getg().m.procid = uint64(gettid())
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
sigdelset(&nmask, i)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
......
...@@ -228,8 +228,6 @@ func minit() { ...@@ -228,8 +228,6 @@ func minit() {
_g_ := getg() _g_ := getg()
_g_.m.procid = uint64(lwp_self()) _g_.m.procid = uint64(lwp_self())
// Initialize signal handling.
// On NetBSD a thread created by pthread_create inherits the // On NetBSD a thread created by pthread_create inherits the
// signal stack of the creating thread. We always create a // signal stack of the creating thread. We always create a
// new signal stack here, to avoid having two Go threads using // new signal stack here, to avoid having two Go threads using
...@@ -240,14 +238,7 @@ func minit() { ...@@ -240,14 +238,7 @@ func minit() {
signalstack(&_g_.m.gsignal.stack) signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true _g_.m.newSigstack = true
// restore signal mask from m.sigmask and unblock essential signals minitSignalMask()
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -317,5 +308,9 @@ func sigmaskToSigset(m sigmask) sigset { ...@@ -317,5 +308,9 @@ func sigmaskToSigset(m sigmask) sigset {
return set return set
} }
func sigdelset(mask *sigset, i int) {
mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
}
func (c *sigctxt) fixsigcode(sig uint32) { func (c *sigctxt) fixsigcode(sig uint32) {
} }
...@@ -213,21 +213,11 @@ func mpreinit(mp *m) { ...@@ -213,21 +213,11 @@ 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() {
_g_ := getg()
// m.procid is a uint64, but tfork writes an int32. Fix it up. // 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))) _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
minitSignalStack() minitSignals()
// restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
nmask &^= 1 << (uint32(i) - 1)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
} }
// Called from dropm to undo the effect of an minit. // Called from dropm to undo the effect of an minit.
...@@ -295,5 +285,9 @@ func sigmaskToSigset(m sigmask) sigset { ...@@ -295,5 +285,9 @@ func sigmaskToSigset(m sigmask) sigset {
return sigset(m[0]) return sigset(m[0])
} }
func sigdelset(mask *sigset, i int) {
*mask &^= 1 << (uint32(i) - 1)
}
func (c *sigctxt) fixsigcode(sig uint32) { func (c *sigctxt) fixsigcode(sig uint32) {
} }
...@@ -573,6 +573,13 @@ func unblocksig(sig int32) { ...@@ -573,6 +573,13 @@ func unblocksig(sig int32) {
sigprocmask(_SIG_UNBLOCK, &set, nil) sigprocmask(_SIG_UNBLOCK, &set, nil)
} }
// minitSignals is called when initializing a new m to set the
// thread's alternate signal stack and signal mask.
func minitSignals() {
minitSignalStack()
minitSignalMask()
}
// minitSignalStack is called when initializing a new m to set the // minitSignalStack is called when initializing a new m to set the
// alternate signal stack. If the alternate signal stack is not set // alternate signal stack. If the alternate signal stack is not set
// for the thread (the normal case) then set the alternate signal // for the thread (the normal case) then set the alternate signal
...@@ -594,6 +601,24 @@ func minitSignalStack() { ...@@ -594,6 +601,24 @@ func minitSignalStack() {
} }
} }
// minitSignalMask is called when initializing a new m to set the
// thread's signal mask. When this is called all signals have been
// blocked for the thread. This starts with m.sigmask, which was set
// either from initSigmask for a newly created thread or by calling
// msigsave if this is a non-Go thread calling a Go function. It
// removes all essential signals from the mask, thus causing those
// signals to not be blocked. Then it sets the thread's signal mask.
// After this is called the thread can receive signals.
func minitSignalMask() {
nmask := getg().m.sigmask
for i := range sigtable {
if sigtable[i].flags&_SigUnblock != 0 {
sigdelset(&nmask, i)
}
}
sigprocmask(_SIG_SETMASK, &nmask, nil)
}
// setGsignalStack sets the gsignal stack of the current m to an // setGsignalStack sets the gsignal stack of the current m to an
// alternate signal stack returned from the sigaltstack system call. // alternate signal stack returned from the sigaltstack system call.
// This is used when handling a signal if non-Go code has set the // This is used when handling a signal if non-Go code has set the
......
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