Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change resolves a TODO in the coroutine switch implementation (used exclusively by iter.Pull at the moment) to enable tracing. This was blocked on eliminating the atomic load in the tracer's "off" path (completed in the previous CL in this series) and the addition of new tracer events to minimize the overhead of tracing in this circumstance. This change introduces 3 new event types to support coroutine switches: GoCreateBlocked, GoSwitch, and GoSwitchDestroy. GoCreateBlocked needs to be introduced because the goroutine created for the coroutine starts out in a blocked state. There's no way to represent this in the tracer right now, so we need a new event for it. GoSwitch represents the actual coroutine switch, which conceptually consists of a GoUnblock, a GoBlock, and a GoStart event in series (unblocking the next goroutine to run, blocking the current goroutine, and then starting the next goroutine to run). GoSwitchDestroy is closely related to GoSwitch, implementing the same semantics except that GoBlock is replaced with GoDestroy. This is used when exiting the coroutine. The implementation of all this is fairly straightforward, and the trace parser simply translates GoSwitch* into the three constituent events. Because GoSwitch and GoSwitchDestroy imply a GoUnblock and a GoStart, they need to synchronize with other past and future GoStart events to create a correct partial ordering in the trace. Therefore, these events need a sequence number for the goroutine that will be unblocked and started. Also, while implementing this, I noticed that the coroutine implementation is actually buggy with respect to LockOSThread. In fact, it blatantly disregards its invariants without an explicit panic. While such a case is likely to be rare (and inefficient!) we should decide how iter.Pull behaves with respect to runtime.LockOSThread. Lastly, this change also bumps the trace version from Go 1.22 to Go 1.23. We're adding events that are incompatible with a Go 1.22 parser, but Go 1.22 traces are all valid Go 1.23 traces, so the newer parser supports both (and the CL otherwise updates the Go 1.22 definitions of events and such). We may want to reconsider the structure and naming of some of these packages though; it could quickly get confusing. For #61897. Change-Id: I96897a46d5852c02691cde9f957dc6c13ef4d8e7 Reviewed-on: https://go-review.googlesource.com/c/go/+/565937 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
- Loading branch information
Showing
14 changed files
with
306 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Tests coroutine switches. | ||
|
||
//go:build ignore | ||
|
||
package main | ||
|
||
import ( | ||
"iter" | ||
"log" | ||
"os" | ||
"runtime/trace" | ||
"sync" | ||
) | ||
|
||
func main() { | ||
// Start tracing. | ||
if err := trace.Start(os.Stdout); err != nil { | ||
log.Fatalf("failed to start tracing: %v", err) | ||
} | ||
|
||
// Try simple pull iteration. | ||
i := pullRange(100) | ||
for { | ||
_, ok := i.next() | ||
if !ok { | ||
break | ||
} | ||
} | ||
|
||
// Try bouncing the pull iterator between two goroutines. | ||
var wg sync.WaitGroup | ||
var iterChans [2]chan intIter | ||
wg.Add(2) | ||
iterChans[0] = make(chan intIter) | ||
iterChans[1] = make(chan intIter) | ||
go func() { | ||
defer wg.Done() | ||
|
||
iter := pullRange(100) | ||
iterChans[1] <- iter | ||
|
||
for i := range iterChans[0] { | ||
_, ok := i.next() | ||
if !ok { | ||
close(iterChans[1]) | ||
break | ||
} | ||
iterChans[1] <- i | ||
} | ||
}() | ||
go func() { | ||
defer wg.Done() | ||
|
||
for i := range iterChans[1] { | ||
_, ok := i.next() | ||
if !ok { | ||
close(iterChans[0]) | ||
break | ||
} | ||
iterChans[0] <- i | ||
} | ||
}() | ||
wg.Wait() | ||
|
||
// End of traced execution. | ||
trace.Stop() | ||
} | ||
|
||
func pullRange(n int) intIter { | ||
next, stop := iter.Pull(func(yield func(v int) bool) { | ||
for i := range n { | ||
yield(i) | ||
} | ||
}) | ||
return intIter{next: next, stop: stop} | ||
} | ||
|
||
type intIter struct { | ||
next func() (int, bool) | ||
stop func() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.