Skip to content

Commit cea35ba

Browse files
committed
runtime: hold sched.lock over traceThreadDestroy in dropm
This is required by traceThreadDestroy, though it's not strictly necessary in this case. The requirement to hold sched.lock comes from the assumption that traceThreadDestroy is getting called when the thread leaves the tracer's view, but in this case the extra m that dropm is dropping never leaves the allm list. Nevertheless, traceThreadDestroy requires it just as a safety measure, and that's reasonable. dropm is generally rare on pthread platforms, so the extra lock acquire over this short critical section (and only when tracing is enabled) is fine. Change-Id: Ib631820963c74f2f087d14a0067d0441d75d6785 Reviewed-on: https://go-review.googlesource.com/c/go/+/544396 Reviewed-by: Matthew Dempsky <[email protected]> Run-TryBot: Michael Knyszek <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 23c0d30 commit cea35ba

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/runtime/proc.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2428,8 +2428,20 @@ func dropm() {
24282428
// Flush all the M's buffers. This is necessary because the M might
24292429
// be used on a different thread with a different procid, so we have
24302430
// to make sure we don't write into the same buffer.
2431-
if traceEnabled() || traceShuttingDown() {
2431+
//
2432+
// N.B. traceThreadDestroy is a no-op in the old tracer, so avoid the
2433+
// unnecessary acquire/release of the lock.
2434+
if goexperiment.ExecTracer2 && (traceEnabled() || traceShuttingDown()) {
2435+
// Acquire sched.lock across thread destruction. One of the invariants of the tracer
2436+
// is that a thread cannot disappear from the tracer's view (allm or freem) without
2437+
// it noticing, so it requires that sched.lock be held over traceThreadDestroy.
2438+
//
2439+
// This isn't strictly necessary in this case, because this thread never leaves allm,
2440+
// but the critical section is short and dropm is rare on pthread platforms, so just
2441+
// take the lock and play it safe. traceThreadDestroy also asserts that the lock is held.
2442+
lock(&sched.lock)
24322443
traceThreadDestroy(mp)
2444+
unlock(&sched.lock)
24332445
}
24342446
mp.isExtraInSig = false
24352447

0 commit comments

Comments
 (0)