Skip to content

Commit f025d19

Browse files
committed
runtime: hold traceAcquire across casgstatus in injectglist
Currently injectglist emits all the trace events before actually calling casgstatus on each goroutine. This is a problem, since tracing can observe an inconsistent state (gstatus does not match tracer's 'emitted an event' state). This change fixes the problem by having injectglist do what every other scheduler function does, and that's wrap each call to casgstatus in traceAcquire/traceRelease. Fixes #70883. Change-Id: I857e96cec01688013597e8efc0c4c3d0b72d3a70 Reviewed-on: https://go-review.googlesource.com/c/go/+/638558 Reviewed-by: Michael Pratt <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 1e9835f commit f025d19

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

src/runtime/proc.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -3894,23 +3894,23 @@ func injectglist(glist *gList) {
38943894
if glist.empty() {
38953895
return
38963896
}
3897-
trace := traceAcquire()
3898-
if trace.ok() {
3899-
for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
3900-
trace.GoUnpark(gp, 0)
3901-
}
3902-
traceRelease(trace)
3903-
}
39043897

39053898
// Mark all the goroutines as runnable before we put them
39063899
// on the run queues.
39073900
head := glist.head.ptr()
39083901
var tail *g
39093902
qsize := 0
3903+
trace := traceAcquire()
39103904
for gp := head; gp != nil; gp = gp.schedlink.ptr() {
39113905
tail = gp
39123906
qsize++
39133907
casgstatus(gp, _Gwaiting, _Grunnable)
3908+
if trace.ok() {
3909+
trace.GoUnpark(gp, 0)
3910+
}
3911+
}
3912+
if trace.ok() {
3913+
traceRelease(trace)
39143914
}
39153915

39163916
// Turn the gList into a gQueue.

0 commit comments

Comments
 (0)