aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index dd6d79f8ec..80fd2d6604 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -336,6 +336,10 @@ func doSigPreempt(gp *g, ctxt *sigctxt) {
// Acknowledge the preemption.
atomic.Xadd(&gp.m.preemptGen, 1)
atomic.Store(&gp.m.signalPending, 0)
+
+ if GOOS == "darwin" {
+ atomic.Xadd(&pendingPreemptSignals, -1)
+ }
}
const preemptMSupported = true
@@ -357,7 +361,18 @@ func preemptM(mp *m) {
// required).
return
}
+
+ // On Darwin, don't try to preempt threads during exec.
+ // Issue #41702.
+ if GOOS == "darwin" {
+ execLock.rlock()
+ }
+
if atomic.Cas(&mp.signalPending, 0, 1) {
+ if GOOS == "darwin" {
+ atomic.Xadd(&pendingPreemptSignals, 1)
+ }
+
// If multiple threads are preempting the same M, it may send many
// signals to the same M such that it hardly make progress, causing
// live-lock problem. Apparently this could happen on darwin. See
@@ -365,6 +380,10 @@ func preemptM(mp *m) {
// Only send a signal if there isn't already one pending.
signalM(mp, sigPreempt)
}
+
+ if GOOS == "darwin" {
+ execLock.runlock()
+ }
}
// sigFetchG fetches the value of G safely when running in a signal handler.
@@ -425,6 +444,9 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
// no non-Go signal handler for sigPreempt.
// The default behavior for sigPreempt is to ignore
// the signal, so badsignal will be a no-op anyway.
+ if GOOS == "darwin" {
+ atomic.Xadd(&pendingPreemptSignals, -1)
+ }
return
}
c.fixsigcode(sig)