File tree 2 files changed +13
-1
lines changed
2 files changed +13
-1
lines changed Original file line number Diff line number Diff line change @@ -540,6 +540,10 @@ type m struct {
540
540
// requested, but fails. Accessed atomically.
541
541
preemptGen uint32
542
542
543
+ // Whether this is a pending preemption signal on this M.
544
+ // Accessed atomically.
545
+ signalPending uint32
546
+
543
547
dlogPerM
544
548
545
549
mOS
Original file line number Diff line number Diff line change @@ -333,6 +333,7 @@ func doSigPreempt(gp *g, ctxt *sigctxt) {
333
333
334
334
// Acknowledge the preemption.
335
335
atomic .Xadd (& gp .m .preemptGen , 1 )
336
+ atomic .Store (& gp .m .signalPending , 0 )
336
337
}
337
338
338
339
const preemptMSupported = pushCallSupported
@@ -359,7 +360,14 @@ func preemptM(mp *m) {
359
360
// required).
360
361
return
361
362
}
362
- signalM (mp , sigPreempt )
363
+ if atomic .Cas (& mp .signalPending , 0 , 1 ) {
364
+ // If multiple threads are preempting the same M, it may send many
365
+ // signals to the same M such that it hardly make progress, causing
366
+ // live-lock problem. Apparently this could happen on darwin. See
367
+ // issue #37741.
368
+ // Only send a signal if there isn't already one pending.
369
+ signalM (mp , sigPreempt )
370
+ }
363
371
}
364
372
365
373
// sigFetchG fetches the value of G safely when running in a signal handler.
You can’t perform that action at this time.
0 commit comments