diff options
| author | Carlos Amedee <carlos@golang.org> | 2024-05-09 10:45:01 -0400 |
|---|---|---|
| committer | Carlos Amedee <carlos@golang.org> | 2024-05-17 18:48:18 +0000 |
| commit | 5890b023a549e7ba6b0c563cdf730a91c2de6fae (patch) | |
| tree | 098ead9c43c885cd3176d6584cc4e54b51253081 /src/cmd/trace | |
| parent | 192d65e46b38381653ccbe16cac49f7fa36aac93 (diff) | |
| download | go-5890b023a549e7ba6b0c563cdf730a91c2de6fae.tar.xz | |
internal/trace: move v2 tracer into trace directory
This change moves the v2 tracer into the trace directory.
Updates #67367
Change-Id: I3657b4227002cb00fdf29c797434800ea796715e
Reviewed-on: https://go-review.googlesource.com/c/go/+/584538
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/trace')
| -rw-r--r-- | src/cmd/trace/gen.go | 101 | ||||
| -rw-r--r-- | src/cmd/trace/goroutinegen.go | 56 | ||||
| -rw-r--r-- | src/cmd/trace/goroutines.go | 5 | ||||
| -rw-r--r-- | src/cmd/trace/gstate.go | 67 | ||||
| -rw-r--r-- | src/cmd/trace/jsontrace.go | 23 | ||||
| -rw-r--r-- | src/cmd/trace/jsontrace_test.go | 6 | ||||
| -rw-r--r-- | src/cmd/trace/main.go | 21 | ||||
| -rw-r--r-- | src/cmd/trace/pprof.go | 61 | ||||
| -rw-r--r-- | src/cmd/trace/procgen.go | 56 | ||||
| -rw-r--r-- | src/cmd/trace/regions.go | 13 | ||||
| -rw-r--r-- | src/cmd/trace/tasks.go | 33 | ||||
| -rw-r--r-- | src/cmd/trace/testdata/mktests.go | 4 | ||||
| -rw-r--r-- | src/cmd/trace/threadgen.go | 56 | ||||
| -rw-r--r-- | src/cmd/trace/viewer.go | 19 |
14 files changed, 256 insertions, 265 deletions
diff --git a/src/cmd/trace/gen.go b/src/cmd/trace/gen.go index b947489037..67811ca04d 100644 --- a/src/cmd/trace/gen.go +++ b/src/cmd/trace/gen.go @@ -8,7 +8,6 @@ import ( "fmt" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "strings" ) @@ -18,21 +17,21 @@ import ( type generator interface { // Global parts. Sync() // Notifies the generator of an EventSync event. - StackSample(ctx *traceContext, ev *tracev2.Event) - GlobalRange(ctx *traceContext, ev *tracev2.Event) - GlobalMetric(ctx *traceContext, ev *tracev2.Event) + StackSample(ctx *traceContext, ev *trace.Event) + GlobalRange(ctx *traceContext, ev *trace.Event) + GlobalMetric(ctx *traceContext, ev *trace.Event) // Goroutine parts. - GoroutineLabel(ctx *traceContext, ev *tracev2.Event) - GoroutineRange(ctx *traceContext, ev *tracev2.Event) - GoroutineTransition(ctx *traceContext, ev *tracev2.Event) + GoroutineLabel(ctx *traceContext, ev *trace.Event) + GoroutineRange(ctx *traceContext, ev *trace.Event) + GoroutineTransition(ctx *traceContext, ev *trace.Event) // Proc parts. - ProcRange(ctx *traceContext, ev *tracev2.Event) - ProcTransition(ctx *traceContext, ev *tracev2.Event) + ProcRange(ctx *traceContext, ev *trace.Event) + ProcTransition(ctx *traceContext, ev *trace.Event) // User annotations. - Log(ctx *traceContext, ev *tracev2.Event) + Log(ctx *traceContext, ev *trace.Event) // Finish indicates the end of the trace and finalizes generation. Finish(ctx *traceContext) @@ -44,35 +43,35 @@ func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace, opts *gen ev := &parsed.events[i] switch ev.Kind() { - case tracev2.EventSync: + case trace.EventSync: g.Sync() - case tracev2.EventStackSample: + case trace.EventStackSample: g.StackSample(ctx, ev) - case tracev2.EventRangeBegin, tracev2.EventRangeActive, tracev2.EventRangeEnd: + case trace.EventRangeBegin, trace.EventRangeActive, trace.EventRangeEnd: r := ev.Range() switch r.Scope.Kind { - case tracev2.ResourceGoroutine: + case trace.ResourceGoroutine: g.GoroutineRange(ctx, ev) - case tracev2.ResourceProc: + case trace.ResourceProc: g.ProcRange(ctx, ev) - case tracev2.ResourceNone: + case trace.ResourceNone: g.GlobalRange(ctx, ev) } - case tracev2.EventMetric: + case trace.EventMetric: g.GlobalMetric(ctx, ev) - case tracev2.EventLabel: + case trace.EventLabel: l := ev.Label() - if l.Resource.Kind == tracev2.ResourceGoroutine { + if l.Resource.Kind == trace.ResourceGoroutine { g.GoroutineLabel(ctx, ev) } - case tracev2.EventStateTransition: + case trace.EventStateTransition: switch ev.StateTransition().Resource.Kind { - case tracev2.ResourceProc: + case trace.ResourceProc: g.ProcTransition(ctx, ev) - case tracev2.ResourceGoroutine: + case trace.ResourceGoroutine: g.GoroutineTransition(ctx, ev) } - case tracev2.EventLog: + case trace.EventLog: g.Log(ctx, ev) } } @@ -93,8 +92,8 @@ func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace, opts *gen // lowest first. func emitTask(ctx *traceContext, task *trace.UserTaskSummary, sortIndex int) { // Collect information about the task. - var startStack, endStack tracev2.Stack - var startG, endG tracev2.GoID + var startStack, endStack trace.Stack + var startG, endG trace.GoID startTime, endTime := ctx.startTime, ctx.endTime if task.Start != nil { startStack = task.Start.Stack() @@ -128,7 +127,7 @@ func emitTask(ctx *traceContext, task *trace.UserTaskSummary, sortIndex int) { Arg: arg, }) // Emit an arrow from the parent to the child. - if task.Parent != nil && task.Start != nil && task.Start.Kind() == tracev2.EventTaskBegin { + if task.Parent != nil && task.Start != nil && task.Start.Kind() == trace.EventTaskBegin { ctx.TaskArrow(traceviewer.ArrowEvent{ Name: "newTask", Start: ctx.elapsed(task.Start.Time()), @@ -151,8 +150,8 @@ func emitRegion(ctx *traceContext, region *trace.UserRegionSummary) { return } // Collect information about the region. - var startStack, endStack tracev2.Stack - goroutine := tracev2.NoGoroutine + var startStack, endStack trace.Stack + goroutine := trace.NoGoroutine startTime, endTime := ctx.startTime, ctx.endTime if region.Start != nil { startStack = region.Start.Stack() @@ -164,7 +163,7 @@ func emitRegion(ctx *traceContext, region *trace.UserRegionSummary) { endTime = region.End.Time() goroutine = region.End.Goroutine() } - if goroutine == tracev2.NoGoroutine { + if goroutine == trace.NoGoroutine { return } arg := struct { @@ -194,11 +193,11 @@ func emitRegion(ctx *traceContext, region *trace.UserRegionSummary) { // The provided resource is the resource the stack sample should count against. type stackSampleGenerator[R resource] struct { // getResource is a function to extract a resource ID from a stack sample event. - getResource func(*tracev2.Event) R + getResource func(*trace.Event) R } // StackSample implements a stack sample event handler. It expects ev to be one such event. -func (g *stackSampleGenerator[R]) StackSample(ctx *traceContext, ev *tracev2.Event) { +func (g *stackSampleGenerator[R]) StackSample(ctx *traceContext, ev *trace.Event) { id := g.getResource(ev) if id == R(noResource) { // We have nowhere to put this in the UI. @@ -213,7 +212,7 @@ func (g *stackSampleGenerator[R]) StackSample(ctx *traceContext, ev *tracev2.Eve } // globalRangeGenerator implements a generic handler for EventRange* events that pertain -// to tracev2.ResourceNone (the global scope). +// to trace.ResourceNone (the global scope). type globalRangeGenerator struct { ranges map[string]activeRange seenSync bool @@ -226,21 +225,21 @@ func (g *globalRangeGenerator) Sync() { // GlobalRange implements a handler for EventRange* events whose Scope.Kind is ResourceNone. // It expects ev to be one such event. -func (g *globalRangeGenerator) GlobalRange(ctx *traceContext, ev *tracev2.Event) { +func (g *globalRangeGenerator) GlobalRange(ctx *traceContext, ev *trace.Event) { if g.ranges == nil { g.ranges = make(map[string]activeRange) } r := ev.Range() switch ev.Kind() { - case tracev2.EventRangeBegin: + case trace.EventRangeBegin: g.ranges[r.Name] = activeRange{ev.Time(), ev.Stack()} - case tracev2.EventRangeActive: + case trace.EventRangeActive: // If we've seen a Sync event, then Active events are always redundant. if !g.seenSync { // Otherwise, they extend back to the start of the trace. g.ranges[r.Name] = activeRange{ctx.startTime, ev.Stack()} } - case tracev2.EventRangeEnd: + case trace.EventRangeEnd: // Only emit GC events, because we have nowhere to // put other events. ar := g.ranges[r.Name] @@ -279,7 +278,7 @@ type globalMetricGenerator struct { } // GlobalMetric implements an event handler for EventMetric events. ev must be one such event. -func (g *globalMetricGenerator) GlobalMetric(ctx *traceContext, ev *tracev2.Event) { +func (g *globalMetricGenerator) GlobalMetric(ctx *traceContext, ev *trace.Event) { m := ev.Metric() switch m.Name { case "/memory/classes/heap/objects:bytes": @@ -294,7 +293,7 @@ func (g *globalMetricGenerator) GlobalMetric(ctx *traceContext, ev *tracev2.Even // procRangeGenerator implements a generic handler for EventRange* events whose Scope.Kind is // ResourceProc. type procRangeGenerator struct { - ranges map[tracev2.Range]activeRange + ranges map[trace.Range]activeRange seenSync bool } @@ -305,21 +304,21 @@ func (g *procRangeGenerator) Sync() { // ProcRange implements a handler for EventRange* events whose Scope.Kind is ResourceProc. // It expects ev to be one such event. -func (g *procRangeGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { +func (g *procRangeGenerator) ProcRange(ctx *traceContext, ev *trace.Event) { if g.ranges == nil { - g.ranges = make(map[tracev2.Range]activeRange) + g.ranges = make(map[trace.Range]activeRange) } r := ev.Range() switch ev.Kind() { - case tracev2.EventRangeBegin: + case trace.EventRangeBegin: g.ranges[r] = activeRange{ev.Time(), ev.Stack()} - case tracev2.EventRangeActive: + case trace.EventRangeActive: // If we've seen a Sync event, then Active events are always redundant. if !g.seenSync { // Otherwise, they extend back to the start of the trace. g.ranges[r] = activeRange{ctx.startTime, ev.Stack()} } - case tracev2.EventRangeEnd: + case trace.EventRangeEnd: // Emit proc-based ranges. ar := g.ranges[r] ctx.Slice(traceviewer.SliceEvent{ @@ -349,27 +348,27 @@ func (g *procRangeGenerator) Finish(ctx *traceContext) { // activeRange represents an active EventRange* range. type activeRange struct { - time tracev2.Time - stack tracev2.Stack + time trace.Time + stack trace.Stack } // completedRange represents a completed EventRange* range. type completedRange struct { name string - startTime tracev2.Time - endTime tracev2.Time - startStack tracev2.Stack - endStack tracev2.Stack + startTime trace.Time + endTime trace.Time + startStack trace.Stack + endStack trace.Stack arg any } type logEventGenerator[R resource] struct { // getResource is a function to extract a resource ID from a Log event. - getResource func(*tracev2.Event) R + getResource func(*trace.Event) R } // Log implements a log event handler. It expects ev to be one such event. -func (g *logEventGenerator[R]) Log(ctx *traceContext, ev *tracev2.Event) { +func (g *logEventGenerator[R]) Log(ctx *traceContext, ev *trace.Event) { id := g.getResource(ev) if id == R(noResource) { // We have nowhere to put this in the UI. diff --git a/src/cmd/trace/goroutinegen.go b/src/cmd/trace/goroutinegen.go index 096aa9972a..385ac37253 100644 --- a/src/cmd/trace/goroutinegen.go +++ b/src/cmd/trace/goroutinegen.go @@ -5,7 +5,7 @@ package main import ( - tracev2 "internal/trace/v2" + "internal/trace" ) var _ generator = &goroutineGenerator{} @@ -13,29 +13,29 @@ var _ generator = &goroutineGenerator{} type goroutineGenerator struct { globalRangeGenerator globalMetricGenerator - stackSampleGenerator[tracev2.GoID] - logEventGenerator[tracev2.GoID] + stackSampleGenerator[trace.GoID] + logEventGenerator[trace.GoID] - gStates map[tracev2.GoID]*gState[tracev2.GoID] - focus tracev2.GoID - filter map[tracev2.GoID]struct{} + gStates map[trace.GoID]*gState[trace.GoID] + focus trace.GoID + filter map[trace.GoID]struct{} } -func newGoroutineGenerator(ctx *traceContext, focus tracev2.GoID, filter map[tracev2.GoID]struct{}) *goroutineGenerator { +func newGoroutineGenerator(ctx *traceContext, focus trace.GoID, filter map[trace.GoID]struct{}) *goroutineGenerator { gg := new(goroutineGenerator) - rg := func(ev *tracev2.Event) tracev2.GoID { + rg := func(ev *trace.Event) trace.GoID { return ev.Goroutine() } gg.stackSampleGenerator.getResource = rg gg.logEventGenerator.getResource = rg - gg.gStates = make(map[tracev2.GoID]*gState[tracev2.GoID]) + gg.gStates = make(map[trace.GoID]*gState[trace.GoID]) gg.focus = focus gg.filter = filter // Enable a filter on the emitter. if filter != nil { ctx.SetResourceFilter(func(resource uint64) bool { - _, ok := filter[tracev2.GoID(resource)] + _, ok := filter[trace.GoID(resource)] return ok }) } @@ -46,25 +46,25 @@ func (g *goroutineGenerator) Sync() { g.globalRangeGenerator.Sync() } -func (g *goroutineGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { +func (g *goroutineGenerator) GoroutineLabel(ctx *traceContext, ev *trace.Event) { l := ev.Label() g.gStates[l.Resource.Goroutine()].setLabel(l.Label) } -func (g *goroutineGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { +func (g *goroutineGenerator) GoroutineRange(ctx *traceContext, ev *trace.Event) { r := ev.Range() switch ev.Kind() { - case tracev2.EventRangeBegin: + case trace.EventRangeBegin: g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: + case trace.EventRangeActive: g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: + case trace.EventRangeEnd: gs := g.gStates[r.Scope.Goroutine()] gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) } } -func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { +func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *trace.Event) { st := ev.StateTransition() goID := st.Resource.Goroutine() @@ -72,7 +72,7 @@ func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2. // gState for it. gs, ok := g.gStates[goID] if !ok { - gs = newGState[tracev2.GoID](goID) + gs = newGState[trace.GoID](goID) g.gStates[goID] = gs } @@ -86,7 +86,7 @@ func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2. return } if from.Executing() && !to.Executing() { - if to == tracev2.GoWaiting { + if to == trace.GoWaiting { // Goroutine started blocking. gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) } else { @@ -95,34 +95,34 @@ func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2. } if !from.Executing() && to.Executing() { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } gs.start(start, goID, ctx) } - if from == tracev2.GoWaiting { + if from == trace.GoWaiting { // Goroutine unblocked. gs.unblock(ev.Time(), ev.Stack(), ev.Goroutine(), ctx) } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + if from == trace.GoNotExist && to == trace.GoRunnable { // Goroutine was created. gs.created(ev.Time(), ev.Goroutine(), ev.Stack()) } - if from == tracev2.GoSyscall && to != tracev2.GoRunning { + if from == trace.GoSyscall && to != trace.GoRunning { // Exiting blocked syscall. gs.syscallEnd(ev.Time(), true, ctx) gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) - } else if from == tracev2.GoSyscall { + } else if from == trace.GoSyscall { // Check if we're exiting a syscall in a non-blocking way. gs.syscallEnd(ev.Time(), false, ctx) } // Handle syscalls. - if to == tracev2.GoSyscall { + if to == trace.GoSyscall { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } @@ -137,12 +137,12 @@ func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2. ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) } -func (g *goroutineGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { +func (g *goroutineGenerator) ProcRange(ctx *traceContext, ev *trace.Event) { // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges // that overlap with a goroutine's execution. } -func (g *goroutineGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { +func (g *goroutineGenerator) ProcTransition(ctx *traceContext, ev *trace.Event) { // Not needed. All relevant information for goroutines can be derived from goroutine transitions. } @@ -161,7 +161,7 @@ func (g *goroutineGenerator) Finish(ctx *traceContext) { } // Set the goroutine to focus on. - if g.focus != tracev2.NoGoroutine { + if g.focus != trace.NoGoroutine { ctx.Focus(uint64(g.focus)) } } diff --git a/src/cmd/trace/goroutines.go b/src/cmd/trace/goroutines.go index be003861a6..7d9d2f3950 100644 --- a/src/cmd/trace/goroutines.go +++ b/src/cmd/trace/goroutines.go @@ -12,7 +12,6 @@ import ( "html/template" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "log" "net/http" "slices" @@ -22,7 +21,7 @@ import ( ) // GoroutinesHandlerFunc returns a HandlerFunc that serves list of goroutine groups. -func GoroutinesHandlerFunc(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { +func GoroutinesHandlerFunc(summaries map[trace.GoID]*trace.GoroutineSummary) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // goroutineGroup describes a group of goroutines grouped by name. type goroutineGroup struct { @@ -95,7 +94,7 @@ Click a start location to view more details about that group.<br> // GoroutineHandler creates a handler that serves information about // goroutines in a particular group. -func GoroutineHandler(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { +func GoroutineHandler(summaries map[trace.GoID]*trace.GoroutineSummary) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { goroutineName := r.FormValue("name") diff --git a/src/cmd/trace/gstate.go b/src/cmd/trace/gstate.go index 4535929093..bcbe3b6c7f 100644 --- a/src/cmd/trace/gstate.go +++ b/src/cmd/trace/gstate.go @@ -9,13 +9,12 @@ import ( "internal/trace" "internal/trace/traceviewer" "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" "strings" ) // resource is a generic constraint interface for resource IDs. type resource interface { - tracev2.GoID | tracev2.ProcID | tracev2.ThreadID + trace.GoID | trace.ProcID | trace.ThreadID } // noResource indicates the lack of a resource. @@ -38,7 +37,7 @@ type gState[R resource] struct { // call to the stop method. This tends to be a more reliable way // of picking up stack traces, since the parser doesn't provide // a stack for every state transition event. - lastStopStack tracev2.Stack + lastStopStack trace.Stack // activeRanges is the set of all active ranges on the goroutine. activeRanges map[string]activeRange @@ -49,13 +48,13 @@ type gState[R resource] struct { // startRunning is the most recent event that caused a goroutine to // transition to GoRunning. - startRunningTime tracev2.Time + startRunningTime trace.Time // startSyscall is the most recent event that caused a goroutine to // transition to GoSyscall. syscall struct { - time tracev2.Time - stack tracev2.Stack + time trace.Time + stack trace.Stack active bool } @@ -71,16 +70,16 @@ type gState[R resource] struct { // listed separately because the cause may have happened on a resource that // isn't R (or perhaps on some abstract nebulous resource, like trace.NetpollP). startCause struct { - time tracev2.Time + time trace.Time name string resource uint64 - stack tracev2.Stack + stack trace.Stack } } // newGState constructs a new goroutine state for the goroutine // identified by the provided ID. -func newGState[R resource](goID tracev2.GoID) *gState[R] { +func newGState[R resource](goID trace.GoID) *gState[R] { return &gState[R]{ baseName: fmt.Sprintf("G%d", goID), executing: R(noResource), @@ -91,11 +90,11 @@ func newGState[R resource](goID tracev2.GoID) *gState[R] { // augmentName attempts to use stk to augment the name of the goroutine // with stack information. This stack must be related to the goroutine // in some way, but it doesn't really matter which stack. -func (gs *gState[R]) augmentName(stk tracev2.Stack) { +func (gs *gState[R]) augmentName(stk trace.Stack) { if gs.named { return } - if stk == tracev2.NoStack { + if stk == trace.NoStack { return } name := lastFunc(stk) @@ -120,7 +119,7 @@ func (gs *gState[R]) name() string { // setStartCause sets the reason a goroutine will be allowed to start soon. // For example, via unblocking or exiting a blocked syscall. -func (gs *gState[R]) setStartCause(ts tracev2.Time, name string, resource uint64, stack tracev2.Stack) { +func (gs *gState[R]) setStartCause(ts trace.Time, name string, resource uint64, stack trace.Stack) { gs.startCause.time = ts gs.startCause.name = name gs.startCause.resource = resource @@ -128,7 +127,7 @@ func (gs *gState[R]) setStartCause(ts tracev2.Time, name string, resource uint64 } // created indicates that this goroutine was just created by the provided creator. -func (gs *gState[R]) created(ts tracev2.Time, creator R, stack tracev2.Stack) { +func (gs *gState[R]) created(ts trace.Time, creator R, stack trace.Stack) { if creator == R(noResource) { return } @@ -136,10 +135,10 @@ func (gs *gState[R]) created(ts tracev2.Time, creator R, stack tracev2.Stack) { } // start indicates that a goroutine has started running on a proc. -func (gs *gState[R]) start(ts tracev2.Time, resource R, ctx *traceContext) { +func (gs *gState[R]) start(ts trace.Time, resource R, ctx *traceContext) { // Set the time for all the active ranges. for name := range gs.activeRanges { - gs.activeRanges[name] = activeRange{ts, tracev2.NoStack} + gs.activeRanges[name] = activeRange{ts, trace.NoStack} } if gs.startCause.name != "" { @@ -155,14 +154,14 @@ func (gs *gState[R]) start(ts tracev2.Time, resource R, ctx *traceContext) { gs.startCause.time = 0 gs.startCause.name = "" gs.startCause.resource = 0 - gs.startCause.stack = tracev2.NoStack + gs.startCause.stack = trace.NoStack } gs.executing = resource gs.startRunningTime = ts } // syscallBegin indicates that the goroutine entered a syscall on a proc. -func (gs *gState[R]) syscallBegin(ts tracev2.Time, resource R, stack tracev2.Stack) { +func (gs *gState[R]) syscallBegin(ts trace.Time, resource R, stack trace.Stack) { gs.syscall.time = ts gs.syscall.stack = stack gs.syscall.active = true @@ -178,7 +177,7 @@ func (gs *gState[R]) syscallBegin(ts tracev2.Time, resource R, stack tracev2.Sta // goroutine is no longer executing on the resource (e.g. a proc) whereas blockedSyscallEnd // is the point at which the goroutine actually exited the syscall regardless of which // resource that happened on. -func (gs *gState[R]) syscallEnd(ts tracev2.Time, blocked bool, ctx *traceContext) { +func (gs *gState[R]) syscallEnd(ts trace.Time, blocked bool, ctx *traceContext) { if !gs.syscall.active { return } @@ -195,13 +194,13 @@ func (gs *gState[R]) syscallEnd(ts tracev2.Time, blocked bool, ctx *traceContext }) gs.syscall.active = false gs.syscall.time = 0 - gs.syscall.stack = tracev2.NoStack + gs.syscall.stack = trace.NoStack } // blockedSyscallEnd indicates the point at which the blocked syscall ended. This is distinct // and orthogonal to syscallEnd; both must be called if the syscall blocked. This sets up an instant // to emit a flow event from, indicating explicitly that this goroutine was unblocked by the system. -func (gs *gState[R]) blockedSyscallEnd(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { +func (gs *gState[R]) blockedSyscallEnd(ts trace.Time, stack trace.Stack, ctx *traceContext) { name := "exit blocked syscall" gs.setStartCause(ts, name, trace.SyscallP, stack) @@ -215,7 +214,7 @@ func (gs *gState[R]) blockedSyscallEnd(ts tracev2.Time, stack tracev2.Stack, ctx } // unblock indicates that the goroutine gs represents has been unblocked. -func (gs *gState[R]) unblock(ts tracev2.Time, stack tracev2.Stack, resource R, ctx *traceContext) { +func (gs *gState[R]) unblock(ts trace.Time, stack trace.Stack, resource R, ctx *traceContext) { name := "unblock" viewerResource := uint64(resource) if gs.startBlockReason != "" { @@ -227,7 +226,7 @@ func (gs *gState[R]) unblock(ts tracev2.Time, stack tracev2.Stack, resource R, c // resource isn't going to be valid in this case. // // TODO(mknyszek): Handle this invalidness in a more general way. - if _, ok := any(resource).(tracev2.ThreadID); !ok { + if _, ok := any(resource).(trace.ThreadID); !ok { // Emit an unblock instant event for the "Network" lane. viewerResource = trace.NetpollP } @@ -246,16 +245,16 @@ func (gs *gState[R]) unblock(ts tracev2.Time, stack tracev2.Stack, resource R, c // block indicates that the goroutine has stopped executing on a proc -- specifically, // it blocked for some reason. -func (gs *gState[R]) block(ts tracev2.Time, stack tracev2.Stack, reason string, ctx *traceContext) { +func (gs *gState[R]) block(ts trace.Time, stack trace.Stack, reason string, ctx *traceContext) { gs.startBlockReason = reason gs.stop(ts, stack, ctx) } // stop indicates that the goroutine has stopped executing on a proc. -func (gs *gState[R]) stop(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { +func (gs *gState[R]) stop(ts trace.Time, stack trace.Stack, ctx *traceContext) { // Emit the execution time slice. var stk int - if gs.lastStopStack != tracev2.NoStack { + if gs.lastStopStack != trace.NoStack { stk = ctx.Stack(viewerFrames(gs.lastStopStack)) } // Check invariants. @@ -304,7 +303,7 @@ func (gs *gState[R]) stop(ts tracev2.Time, stack tracev2.Stack, ctx *traceContex // Clear the range info. for name := range gs.activeRanges { - gs.activeRanges[name] = activeRange{0, tracev2.NoStack} + gs.activeRanges[name] = activeRange{0, trace.NoStack} } gs.startRunningTime = 0 @@ -319,12 +318,12 @@ func (gs *gState[R]) stop(ts tracev2.Time, stack tracev2.Stack, ctx *traceContex func (gs *gState[R]) finish(ctx *traceContext) { if gs.executing != R(noResource) { gs.syscallEnd(ctx.endTime, false, ctx) - gs.stop(ctx.endTime, tracev2.NoStack, ctx) + gs.stop(ctx.endTime, trace.NoStack, ctx) } } // rangeBegin indicates the start of a special range of time. -func (gs *gState[R]) rangeBegin(ts tracev2.Time, name string, stack tracev2.Stack) { +func (gs *gState[R]) rangeBegin(ts trace.Time, name string, stack trace.Stack) { if gs.executing != R(noResource) { // If we're executing, start the slice from here. gs.activeRanges[name] = activeRange{ts, stack} @@ -340,16 +339,16 @@ func (gs *gState[R]) rangeActive(name string) { if gs.executing != R(noResource) { // If we're executing, and the range is active, then start // from wherever the goroutine started running from. - gs.activeRanges[name] = activeRange{gs.startRunningTime, tracev2.NoStack} + gs.activeRanges[name] = activeRange{gs.startRunningTime, trace.NoStack} } else { // If the goroutine isn't executing, there's no place for // us to create a slice from. Wait until it starts executing. - gs.activeRanges[name] = activeRange{0, tracev2.NoStack} + gs.activeRanges[name] = activeRange{0, trace.NoStack} } } // rangeEnd indicates the end of a special range of time. -func (gs *gState[R]) rangeEnd(ts tracev2.Time, name string, stack tracev2.Stack, ctx *traceContext) { +func (gs *gState[R]) rangeEnd(ts trace.Time, name string, stack trace.Stack, ctx *traceContext) { if gs.executing != R(noResource) { r := gs.activeRanges[name] gs.completedRanges = append(gs.completedRanges, completedRange{ @@ -363,9 +362,9 @@ func (gs *gState[R]) rangeEnd(ts tracev2.Time, name string, stack tracev2.Stack, delete(gs.activeRanges, name) } -func lastFunc(s tracev2.Stack) string { - var last tracev2.StackFrame - s.Frames(func(f tracev2.StackFrame) bool { +func lastFunc(s trace.Stack) string { + var last trace.StackFrame + s.Frames(func(f trace.StackFrame) bool { last = f return true }) diff --git a/src/cmd/trace/jsontrace.go b/src/cmd/trace/jsontrace.go index cdb1cd65bb..bd3957ab84 100644 --- a/src/cmd/trace/jsontrace.go +++ b/src/cmd/trace/jsontrace.go @@ -15,7 +15,6 @@ import ( "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" ) func JSONTraceHandler(parsed *parsedTrace) http.Handler { @@ -34,7 +33,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { log.Printf("failed to parse goid parameter %q: %v", goids, err) return } - goid := tracev2.GoID(id) + goid := trace.GoID(id) g, ok := parsed.summary.Goroutines[goid] if !ok { log.Printf("failed to find goroutine %d", goid) @@ -59,7 +58,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { log.Printf("failed to parse focustask parameter %q: %v", taskids, err) return } - task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] + task, ok := parsed.summary.Tasks[trace.TaskID(taskid)] if !ok || (task.Start == nil && task.End == nil) { log.Printf("failed to find task with id %d", taskid) return @@ -71,7 +70,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { log.Printf("failed to parse taskid parameter %q: %v", taskids, err) return } - task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] + task, ok := parsed.summary.Tasks[trace.TaskID(taskid)] if !ok { log.Printf("failed to find task with id %d", taskid) return @@ -83,7 +82,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { // Pick the goroutine to orient ourselves around by just // trying to pick the earliest event in the task that makes // any sense. Though, we always want the start if that's there. - var firstEv *tracev2.Event + var firstEv *trace.Event if task.Start != nil { firstEv = task.Start } else { @@ -96,7 +95,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { firstEv = task.End } } - if firstEv == nil || firstEv.Goroutine() == tracev2.NoGoroutine { + if firstEv == nil || firstEv.Goroutine() == trace.NoGoroutine { log.Printf("failed to find task with id %d", taskid) return } @@ -104,7 +103,7 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { // Set the goroutine filtering options. goid := firstEv.Goroutine() opts.focusGoroutine = goid - goroutines := make(map[tracev2.GoID]struct{}) + goroutines := make(map[trace.GoID]struct{}) for _, task := range opts.tasks { // Find only directly involved goroutines. for id := range task.Goroutines { @@ -143,13 +142,13 @@ func JSONTraceHandler(parsed *parsedTrace) http.Handler { // information that's useful to most parts of trace viewer JSON emission. type traceContext struct { *traceviewer.Emitter - startTime tracev2.Time - endTime tracev2.Time + startTime trace.Time + endTime trace.Time } // elapsed returns the elapsed time between the trace time and the start time // of the trace. -func (ctx *traceContext) elapsed(now tracev2.Time) time.Duration { +func (ctx *traceContext) elapsed(now trace.Time) time.Duration { return now.Sub(ctx.startTime) } @@ -159,8 +158,8 @@ type genOpts struct { endTime time.Duration // Used if mode != 0. - focusGoroutine tracev2.GoID - goroutines map[tracev2.GoID]struct{} // Goroutines to be displayed for goroutine-oriented or task-oriented view. goroutines[0] is the main goroutine. + focusGoroutine trace.GoID + goroutines map[trace.GoID]struct{} // Goroutines to be displayed for goroutine-oriented or task-oriented view. goroutines[0] is the main goroutine. tasks []*trace.UserTaskSummary } diff --git a/src/cmd/trace/jsontrace_test.go b/src/cmd/trace/jsontrace_test.go index 74b37a239f..5f89b275dc 100644 --- a/src/cmd/trace/jsontrace_test.go +++ b/src/cmd/trace/jsontrace_test.go @@ -7,7 +7,7 @@ package main import ( "bytes" "encoding/json" - tracev1 "internal/trace" + "internal/trace" "io" "net/http/httptest" "os" @@ -18,8 +18,8 @@ import ( "testing" "time" + "internal/trace/raw" "internal/trace/traceviewer/format" - "internal/trace/v2/raw" ) func TestJSONTraceHandler(t *testing.T) { @@ -159,7 +159,7 @@ func checkNetworkUnblock(t *testing.T, data format.Data) { count := 0 var netBlockEv *format.Event for _, e := range data.Events { - if e.TID == tracev1.NetpollP && e.Name == "unblock (network)" && e.Phase == "I" && e.Scope == "t" { + if e.TID == trace.NetpollP && e.Name == "unblock (network)" && e.Phase == "I" && e.Scope == "t" { count++ netBlockEv = e } diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go index 44a6d3c74f..16721ef842 100644 --- a/src/cmd/trace/main.go +++ b/src/cmd/trace/main.go @@ -10,9 +10,8 @@ import ( "flag" "fmt" "internal/trace" + "internal/trace/raw" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "internal/trace/v2/raw" "io" "log" "net" @@ -252,7 +251,7 @@ progressLoop: } type parsedTrace struct { - events []tracev2.Event + events []trace.Event summary *trace.Summary size, valid int64 err error @@ -261,7 +260,7 @@ type parsedTrace struct { func parseTrace(rr io.Reader, size int64) (*parsedTrace, error) { // Set up the reader. cr := countingReader{r: rr} - r, err := tracev2.NewReader(&cr) + r, err := trace.NewReader(&cr) if err != nil { return nil, fmt.Errorf("failed to create trace reader: %w", err) } @@ -285,7 +284,7 @@ func parseTrace(rr io.Reader, size int64) (*parsedTrace, error) { t.events = append(t.events, ev) s.Event(&t.events[len(t.events)-1]) - if ev.Kind() == tracev2.EventSync { + if ev.Kind() == trace.EventSync { validBytes = cr.bytesRead.Load() validEvents = len(t.events) } @@ -304,11 +303,11 @@ func parseTrace(rr io.Reader, size int64) (*parsedTrace, error) { return t, nil } -func (t *parsedTrace) startTime() tracev2.Time { +func (t *parsedTrace) startTime() trace.Time { return t.events[0].Time() } -func (t *parsedTrace) endTime() tracev2.Time { +func (t *parsedTrace) endTime() trace.Time { return t.events[len(t.events)-1].Time() } @@ -324,8 +323,8 @@ func splitTrace(parsed *parsedTrace) ([]traceviewer.Range, error) { return s.Ranges, nil } -func debugProcessedEvents(trace io.Reader) error { - tr, err := tracev2.NewReader(trace) +func debugProcessedEvents(trc io.Reader) error { + tr, err := trace.NewReader(trc) if err != nil { return err } @@ -340,8 +339,8 @@ func debugProcessedEvents(trace io.Reader) error { } } -func debugRawEvents(trace io.Reader) error { - rr, err := raw.NewReader(trace) +func debugRawEvents(trc io.Reader) error { + rr, err := raw.NewReader(trc) if err != nil { return err } diff --git a/src/cmd/trace/pprof.go b/src/cmd/trace/pprof.go index e921b38fca..c3e5a3a045 100644 --- a/src/cmd/trace/pprof.go +++ b/src/cmd/trace/pprof.go @@ -11,7 +11,6 @@ import ( "fmt" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "net/http" "slices" "strings" @@ -45,8 +44,8 @@ func pprofByRegion(compute computePprofFunc, t *parsedTrace) traceviewer.Profile // pprofMatchingGoroutines returns the ids of goroutines of the matching name and its interval. // If the id string is empty, returns nil without an error. -func pprofMatchingGoroutines(name string, t *parsedTrace) (map[tracev2.GoID][]interval, error) { - res := make(map[tracev2.GoID][]interval) +func pprofMatchingGoroutines(name string, t *parsedTrace) (map[trace.GoID][]interval, error) { + res := make(map[trace.GoID][]interval) for _, g := range t.summary.Goroutines { if name != "" && g.Name != name { continue @@ -65,12 +64,12 @@ func pprofMatchingGoroutines(name string, t *parsedTrace) (map[tracev2.GoID][]in // pprofMatchingRegions returns the time intervals of matching regions // grouped by the goroutine id. If the filter is nil, returns nil without an error. -func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[tracev2.GoID][]interval, error) { +func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[trace.GoID][]interval, error) { if filter == nil { return nil, nil } - gToIntervals := make(map[tracev2.GoID][]interval) + gToIntervals := make(map[trace.GoID][]interval) for _, g := range t.summary.Goroutines { for _, r := range g.Regions { if !filter.match(t, r) { @@ -91,7 +90,7 @@ func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[tracev2.GoI } return cmp.Compare(a.end, b.end) }) - var lastTimestamp tracev2.Time + var lastTimestamp trace.Time var n int // Select only the outermost regions. for _, i := range intervals { @@ -107,12 +106,12 @@ func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[tracev2.GoI return gToIntervals, nil } -type computePprofFunc func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) +type computePprofFunc func(gToIntervals map[trace.GoID][]interval, events []trace.Event) ([]traceviewer.ProfileRecord, error) // computePprofIO returns a computePprofFunc that generates IO pprof-like profile (time spent in // IO wait, currently only network blocking event). func computePprofIO() computePprofFunc { - return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { + return makeComputePprofFunc(trace.GoWaiting, func(reason string) bool { return reason == "network" }) } @@ -120,7 +119,7 @@ func computePprofIO() computePprofFunc { // computePprofBlock returns a computePprofFunc that generates blocking pprof-like profile // (time spent blocked on synchronization primitives). func computePprofBlock() computePprofFunc { - return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { + return makeComputePprofFunc(trace.GoWaiting, func(reason string) bool { return strings.Contains(reason, "chan") || strings.Contains(reason, "sync") || strings.Contains(reason, "select") }) } @@ -128,7 +127,7 @@ func computePprofBlock() computePprofFunc { // computePprofSyscall returns a computePprofFunc that generates a syscall pprof-like // profile (time spent in syscalls). func computePprofSyscall() computePprofFunc { - return makeComputePprofFunc(tracev2.GoSyscall, func(_ string) bool { + return makeComputePprofFunc(trace.GoSyscall, func(_ string) bool { return true }) } @@ -136,32 +135,32 @@ func computePprofSyscall() computePprofFunc { // computePprofSched returns a computePprofFunc that generates a scheduler latency pprof-like profile // (time between a goroutine become runnable and actually scheduled for execution). func computePprofSched() computePprofFunc { - return makeComputePprofFunc(tracev2.GoRunnable, func(_ string) bool { + return makeComputePprofFunc(trace.GoRunnable, func(_ string) bool { return true }) } // makeComputePprofFunc returns a computePprofFunc that generates a profile of time goroutines spend // in a particular state for the specified reasons. -func makeComputePprofFunc(state tracev2.GoState, trackReason func(string) bool) computePprofFunc { - return func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) { +func makeComputePprofFunc(state trace.GoState, trackReason func(string) bool) computePprofFunc { + return func(gToIntervals map[trace.GoID][]interval, events []trace.Event) ([]traceviewer.ProfileRecord, error) { stacks := newStackMap() - tracking := make(map[tracev2.GoID]*tracev2.Event) + tracking := make(map[trace.GoID]*trace.Event) for i := range events { ev := &events[i] // Filter out any non-state-transitions and events without stacks. - if ev.Kind() != tracev2.EventStateTransition { + if ev.Kind() != trace.EventStateTransition { continue } stack := ev.Stack() - if stack == tracev2.NoStack { + if stack == trace.NoStack { continue } // The state transition has to apply to a goroutine. st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { + if st.Resource.Kind != trace.ResourceGoroutine { continue } id := st.Resource.Goroutine() @@ -202,7 +201,7 @@ func makeComputePprofFunc(state tracev2.GoState, trackReason func(string) bool) // pprofOverlappingDuration returns the overlapping duration between // the time intervals in gToIntervals and the specified event. // If gToIntervals is nil, this simply returns the event's duration. -func pprofOverlappingDuration(gToIntervals map[tracev2.GoID][]interval, id tracev2.GoID, sample interval) time.Duration { +func pprofOverlappingDuration(gToIntervals map[trace.GoID][]interval, id trace.GoID, sample interval) time.Duration { if gToIntervals == nil { // No filtering. return sample.duration() } @@ -222,7 +221,7 @@ func pprofOverlappingDuration(gToIntervals map[tracev2.GoID][]interval, id trace // interval represents a time interval in the trace. type interval struct { - start, end tracev2.Time + start, end trace.Time } func (i interval) duration() time.Duration { @@ -251,28 +250,28 @@ func (i1 interval) overlap(i2 interval) time.Duration { // stacks anyway. const pprofMaxStack = 128 -// stackMap is a map of tracev2.Stack to some value V. +// stackMap is a map of trace.Stack to some value V. type stackMap struct { // stacks contains the full list of stacks in the set, however - // it is insufficient for deduplication because tracev2.Stack - // equality is only optimistic. If two tracev2.Stacks are equal, + // it is insufficient for deduplication because trace.Stack + // equality is only optimistic. If two trace.Stacks are equal, // then they are guaranteed to be equal in content. If they are // not equal, then they might still be equal in content. - stacks map[tracev2.Stack]*traceviewer.ProfileRecord + stacks map[trace.Stack]*traceviewer.ProfileRecord // pcs is the source-of-truth for deduplication. It is a map of - // the actual PCs in the stack to a tracev2.Stack. - pcs map[[pprofMaxStack]uint64]tracev2.Stack + // the actual PCs in the stack to a trace.Stack. + pcs map[[pprofMaxStack]uint64]trace.Stack } func newStackMap() *stackMap { return &stackMap{ - stacks: make(map[tracev2.Stack]*traceviewer.ProfileRecord), - pcs: make(map[[pprofMaxStack]uint64]tracev2.Stack), + stacks: make(map[trace.Stack]*traceviewer.ProfileRecord), + pcs: make(map[[pprofMaxStack]uint64]trace.Stack), } } -func (m *stackMap) getOrAdd(stack tracev2.Stack) *traceviewer.ProfileRecord { +func (m *stackMap) getOrAdd(stack trace.Stack) *traceviewer.ProfileRecord { // Fast path: check to see if this exact stack is already in the map. if rec, ok := m.stacks[stack]; ok { return rec @@ -308,7 +307,7 @@ func (m *stackMap) profile() []traceviewer.ProfileRecord { for stack, record := range m.stacks { rec := *record i := 0 - stack.Frames(func(frame tracev2.StackFrame) bool { + stack.Frames(func(frame trace.StackFrame) bool { rec.Stack = append(rec.Stack, &trace.Frame{ PC: frame.PC, Fn: frame.Func, @@ -326,9 +325,9 @@ func (m *stackMap) profile() []traceviewer.ProfileRecord { } // pcsForStack extracts the first pprofMaxStack PCs from stack into pcs. -func pcsForStack(stack tracev2.Stack, pcs *[pprofMaxStack]uint64) { +func pcsForStack(stack trace.Stack, pcs *[pprofMaxStack]uint64) { i := 0 - stack.Frames(func(frame tracev2.StackFrame) bool { + stack.Frames(func(frame trace.StackFrame) bool { pcs[i] = frame.PC i++ return i < len(pcs) diff --git a/src/cmd/trace/procgen.go b/src/cmd/trace/procgen.go index 7dd724bb78..060e62fe04 100644 --- a/src/cmd/trace/procgen.go +++ b/src/cmd/trace/procgen.go @@ -6,9 +6,9 @@ package main import ( "fmt" + "internal/trace" "internal/trace/traceviewer" "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" ) var _ generator = &procGenerator{} @@ -17,23 +17,23 @@ type procGenerator struct { globalRangeGenerator globalMetricGenerator procRangeGenerator - stackSampleGenerator[tracev2.ProcID] - logEventGenerator[tracev2.ProcID] + stackSampleGenerator[trace.ProcID] + logEventGenerator[trace.ProcID] - gStates map[tracev2.GoID]*gState[tracev2.ProcID] - inSyscall map[tracev2.ProcID]*gState[tracev2.ProcID] - maxProc tracev2.ProcID + gStates map[trace.GoID]*gState[trace.ProcID] + inSyscall map[trace.ProcID]*gState[trace.ProcID] + maxProc trace.ProcID } func newProcGenerator() *procGenerator { pg := new(procGenerator) - rg := func(ev *tracev2.Event) tracev2.ProcID { + rg := func(ev *trace.Event) trace.ProcID { return ev.Proc() } pg.stackSampleGenerator.getResource = rg pg.logEventGenerator.getResource = rg - pg.gStates = make(map[tracev2.GoID]*gState[tracev2.ProcID]) - pg.inSyscall = make(map[tracev2.ProcID]*gState[tracev2.ProcID]) + pg.gStates = make(map[trace.GoID]*gState[trace.ProcID]) + pg.inSyscall = make(map[trace.ProcID]*gState[trace.ProcID]) return pg } @@ -42,25 +42,25 @@ func (g *procGenerator) Sync() { g.procRangeGenerator.Sync() } -func (g *procGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { +func (g *procGenerator) GoroutineLabel(ctx *traceContext, ev *trace.Event) { l := ev.Label() g.gStates[l.Resource.Goroutine()].setLabel(l.Label) } -func (g *procGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { +func (g *procGenerator) GoroutineRange(ctx *traceContext, ev *trace.Event) { r := ev.Range() switch ev.Kind() { - case tracev2.EventRangeBegin: + case trace.EventRangeBegin: g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: + case trace.EventRangeActive: g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: + case trace.EventRangeEnd: gs := g.gStates[r.Scope.Goroutine()] gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) } } -func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { +func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *trace.Event) { st := ev.StateTransition() goID := st.Resource.Goroutine() @@ -68,7 +68,7 @@ func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event // gState for it. gs, ok := g.gStates[goID] if !ok { - gs = newGState[tracev2.ProcID](goID) + gs = newGState[trace.ProcID](goID) g.gStates[goID] = gs } // If we haven't already named this goroutine, try to name it. @@ -80,40 +80,40 @@ func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event // Filter out no-op events. return } - if from == tracev2.GoRunning && !to.Executing() { - if to == tracev2.GoWaiting { + if from == trace.GoRunning && !to.Executing() { + if to == trace.GoWaiting { // Goroutine started blocking. gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) } else { gs.stop(ev.Time(), ev.Stack(), ctx) } } - if !from.Executing() && to == tracev2.GoRunning { + if !from.Executing() && to == trace.GoRunning { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } gs.start(start, ev.Proc(), ctx) } - if from == tracev2.GoWaiting { + if from == trace.GoWaiting { // Goroutine was unblocked. gs.unblock(ev.Time(), ev.Stack(), ev.Proc(), ctx) } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + if from == trace.GoNotExist && to == trace.GoRunnable { // Goroutine was created. gs.created(ev.Time(), ev.Proc(), ev.Stack()) } - if from == tracev2.GoSyscall && to != tracev2.GoRunning { + if from == trace.GoSyscall && to != trace.GoRunning { // Goroutine exited a blocked syscall. gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) } // Handle syscalls. - if to == tracev2.GoSyscall && ev.Proc() != tracev2.NoProc { + if to == trace.GoSyscall && ev.Proc() != trace.NoProc { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } @@ -125,7 +125,7 @@ func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event } // Check if we're exiting a non-blocking syscall. _, didNotBlock := g.inSyscall[ev.Proc()] - if from == tracev2.GoSyscall && didNotBlock { + if from == trace.GoSyscall && didNotBlock { gs.syscallEnd(ev.Time(), false, ctx) delete(g.inSyscall, ev.Proc()) } @@ -135,7 +135,7 @@ func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) } -func (g *procGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { +func (g *procGenerator) ProcTransition(ctx *traceContext, ev *trace.Event) { st := ev.StateTransition() proc := st.Resource.Proc() @@ -152,7 +152,7 @@ func (g *procGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { } if to.Executing() { start := ev.Time() - if from == tracev2.ProcUndetermined { + if from == trace.ProcUndetermined { start = ctx.startTime } viewerEv.Name = "proc start" diff --git a/src/cmd/trace/regions.go b/src/cmd/trace/regions.go index a85ed176f0..cb04190fd8 100644 --- a/src/cmd/trace/regions.go +++ b/src/cmd/trace/regions.go @@ -10,7 +10,6 @@ import ( "html/template" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "net/http" "net/url" "slices" @@ -59,7 +58,7 @@ func UserRegionsHandlerFunc(t *parsedTrace) http.HandlerFunc { // regionFingerprint is a way to categorize regions that goes just one step beyond the region's Type // by including the top stack frame. type regionFingerprint struct { - Frame tracev2.StackFrame + Frame trace.StackFrame Type string } @@ -70,10 +69,10 @@ func fingerprintRegion(r *trace.UserRegionSummary) regionFingerprint { } } -func regionTopStackFrame(r *trace.UserRegionSummary) tracev2.StackFrame { - var frame tracev2.StackFrame - if r.Start != nil && r.Start.Stack() != tracev2.NoStack { - r.Start.Stack().Frames(func(f tracev2.StackFrame) bool { +func regionTopStackFrame(r *trace.UserRegionSummary) trace.StackFrame { + var frame trace.StackFrame + if r.Start != nil && r.Start.Stack() != trace.NoStack { + r.Start.Stack().Frames(func(f trace.StackFrame) bool { frame = f return false }) @@ -167,7 +166,7 @@ func UserRegionHandlerFunc(t *parsedTrace) http.HandlerFunc { // Collect all the regions with their goroutines. type region struct { *trace.UserRegionSummary - Goroutine tracev2.GoID + Goroutine trace.GoID NonOverlappingStats map[string]time.Duration HasRangeTime bool } diff --git a/src/cmd/trace/tasks.go b/src/cmd/trace/tasks.go index 8c7b6bad88..8cb5a83a08 100644 --- a/src/cmd/trace/tasks.go +++ b/src/cmd/trace/tasks.go @@ -11,7 +11,6 @@ import ( "html/template" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "log" "net/http" "slices" @@ -126,13 +125,13 @@ func UserTaskHandlerFunc(t *parsedTrace) http.HandlerFunc { type event struct { WhenString string Elapsed time.Duration - Goroutine tracev2.GoID + Goroutine trace.GoID What string // TODO: include stack trace of creation time } type task struct { WhenString string - ID tracev2.TaskID + ID trace.TaskID Duration time.Duration Complete bool Events []event @@ -146,7 +145,7 @@ func UserTaskHandlerFunc(t *parsedTrace) http.HandlerFunc { } // Collect all the events for the task. - var rawEvents []*tracev2.Event + var rawEvents []*trace.Event if summary.Start != nil { rawEvents = append(rawEvents, summary.Start) } @@ -164,7 +163,7 @@ func UserTaskHandlerFunc(t *parsedTrace) http.HandlerFunc { } // Sort them. - slices.SortStableFunc(rawEvents, func(a, b *tracev2.Event) int { + slices.SortStableFunc(rawEvents, func(a, b *trace.Event) int { return cmp.Compare(a.Time(), b.Time()) }) @@ -412,25 +411,25 @@ func taskMatches(t *trace.UserTaskSummary, text string) bool { return false } -func describeEvent(ev *tracev2.Event) string { +func describeEvent(ev *trace.Event) string { switch ev.Kind() { - case tracev2.EventStateTransition: + case trace.EventStateTransition: st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { + if st.Resource.Kind != trace.ResourceGoroutine { return "" } old, new := st.Goroutine() return fmt.Sprintf("%s -> %s", old, new) - case tracev2.EventRegionBegin: + case trace.EventRegionBegin: return fmt.Sprintf("region %q begin", ev.Region().Type) - case tracev2.EventRegionEnd: + case trace.EventRegionEnd: return fmt.Sprintf("region %q end", ev.Region().Type) - case tracev2.EventTaskBegin: + case trace.EventTaskBegin: t := ev.Task() return fmt.Sprintf("task %q (D %d, parent %d) begin", t.Type, t.ID, t.Parent) - case tracev2.EventTaskEnd: + case trace.EventTaskEnd: return "task end" - case tracev2.EventLog: + case trace.EventLog: log := ev.Log() if log.Category != "" { return fmt.Sprintf("log %q", log.Message) @@ -440,13 +439,13 @@ func describeEvent(ev *tracev2.Event) string { return "" } -func primaryGoroutine(ev *tracev2.Event) tracev2.GoID { - if ev.Kind() != tracev2.EventStateTransition { +func primaryGoroutine(ev *trace.Event) trace.GoID { + if ev.Kind() != trace.EventStateTransition { return ev.Goroutine() } st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { - return tracev2.NoGoroutine + if st.Resource.Kind != trace.ResourceGoroutine { + return trace.NoGoroutine } return st.Resource.Goroutine() } diff --git a/src/cmd/trace/testdata/mktests.go b/src/cmd/trace/testdata/mktests.go index b6efa83ece..8eddc7f8af 100644 --- a/src/cmd/trace/testdata/mktests.go +++ b/src/cmd/trace/testdata/mktests.go @@ -9,8 +9,8 @@ package main import ( "bytes" "fmt" - "internal/trace/v2/raw" - "internal/trace/v2/version" + "internal/trace/raw" + "internal/trace/version" "io" "log" "os" diff --git a/src/cmd/trace/threadgen.go b/src/cmd/trace/threadgen.go index 2d2c7eb753..c2e2c86f6c 100644 --- a/src/cmd/trace/threadgen.go +++ b/src/cmd/trace/threadgen.go @@ -6,9 +6,9 @@ package main import ( "fmt" + "internal/trace" "internal/trace/traceviewer" "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" ) var _ generator = &threadGenerator{} @@ -16,22 +16,22 @@ var _ generator = &threadGenerator{} type threadGenerator struct { globalRangeGenerator globalMetricGenerator - stackSampleGenerator[tracev2.ThreadID] - logEventGenerator[tracev2.ThreadID] + stackSampleGenerator[trace.ThreadID] + logEventGenerator[trace.ThreadID] - gStates map[tracev2.GoID]*gState[tracev2.ThreadID] - threads map[tracev2.ThreadID]struct{} + gStates map[trace.GoID]*gState[trace.ThreadID] + threads map[trace.ThreadID]struct{} } func newThreadGenerator() *threadGenerator { tg := new(threadGenerator) - rg := func(ev *tracev2.Event) tracev2.ThreadID { + rg := func(ev *trace.Event) trace.ThreadID { return ev.Thread() } tg.stackSampleGenerator.getResource = rg tg.logEventGenerator.getResource = rg - tg.gStates = make(map[tracev2.GoID]*gState[tracev2.ThreadID]) - tg.threads = make(map[tracev2.ThreadID]struct{}) + tg.gStates = make(map[trace.GoID]*gState[trace.ThreadID]) + tg.threads = make(map[trace.ThreadID]struct{}) return tg } @@ -39,26 +39,26 @@ func (g *threadGenerator) Sync() { g.globalRangeGenerator.Sync() } -func (g *threadGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { +func (g *threadGenerator) GoroutineLabel(ctx *traceContext, ev *trace.Event) { l := ev.Label() g.gStates[l.Resource.Goroutine()].setLabel(l.Label) } -func (g *threadGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { +func (g *threadGenerator) GoroutineRange(ctx *traceContext, ev *trace.Event) { r := ev.Range() switch ev.Kind() { - case tracev2.EventRangeBegin: + case trace.EventRangeBegin: g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: + case trace.EventRangeActive: g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: + case trace.EventRangeEnd: gs := g.gStates[r.Scope.Goroutine()] gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) } } -func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { - if ev.Thread() != tracev2.NoThread { +func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *trace.Event) { + if ev.Thread() != trace.NoThread { if _, ok := g.threads[ev.Thread()]; !ok { g.threads[ev.Thread()] = struct{}{} } @@ -71,7 +71,7 @@ func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Eve // gState for it. gs, ok := g.gStates[goID] if !ok { - gs = newGState[tracev2.ThreadID](goID) + gs = newGState[trace.ThreadID](goID) g.gStates[goID] = gs } // If we haven't already named this goroutine, try to name it. @@ -84,7 +84,7 @@ func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Eve return } if from.Executing() && !to.Executing() { - if to == tracev2.GoWaiting { + if to == trace.GoWaiting { // Goroutine started blocking. gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) } else { @@ -93,30 +93,30 @@ func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Eve } if !from.Executing() && to.Executing() { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } gs.start(start, ev.Thread(), ctx) } - if from == tracev2.GoWaiting { + if from == trace.GoWaiting { // Goroutine was unblocked. gs.unblock(ev.Time(), ev.Stack(), ev.Thread(), ctx) } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + if from == trace.GoNotExist && to == trace.GoRunnable { // Goroutine was created. gs.created(ev.Time(), ev.Thread(), ev.Stack()) } - if from == tracev2.GoSyscall { + if from == trace.GoSyscall { // Exiting syscall. - gs.syscallEnd(ev.Time(), to != tracev2.GoRunning, ctx) + gs.syscallEnd(ev.Time(), to != trace.GoRunning, ctx) } // Handle syscalls. - if to == tracev2.GoSyscall { + if to == trace.GoSyscall { start := ev.Time() - if from == tracev2.GoUndetermined { + if from == trace.GoUndetermined { // Back-date the event to the start of the trace. start = ctx.startTime } @@ -131,8 +131,8 @@ func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Eve ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) } -func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { - if ev.Thread() != tracev2.NoThread { +func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *trace.Event) { + if ev.Thread() != trace.NoThread { if _, ok := g.threads[ev.Thread()]; !ok { g.threads[ev.Thread()] = struct{}{} } @@ -155,7 +155,7 @@ func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { } if to.Executing() { start := ev.Time() - if from == tracev2.ProcUndetermined { + if from == trace.ProcUndetermined { start = ctx.startTime } viewerEv.Name = "proc start" @@ -182,7 +182,7 @@ func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { } } -func (g *threadGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { +func (g *threadGenerator) ProcRange(ctx *traceContext, ev *trace.Event) { // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges on threads. } diff --git a/src/cmd/trace/viewer.go b/src/cmd/trace/viewer.go index 6d3029ac86..79c9583b0d 100644 --- a/src/cmd/trace/viewer.go +++ b/src/cmd/trace/viewer.go @@ -8,15 +8,14 @@ import ( "fmt" "internal/trace" "internal/trace/traceviewer" - tracev2 "internal/trace/v2" "time" ) // viewerFrames returns the frames of the stack of ev. The given frame slice is // used to store the frames to reduce allocations. -func viewerFrames(stk tracev2.Stack) []*trace.Frame { +func viewerFrames(stk trace.Stack) []*trace.Frame { var frames []*trace.Frame - stk.Frames(func(f tracev2.StackFrame) bool { + stk.Frames(func(f trace.StackFrame) bool { frames = append(frames, &trace.Frame{ PC: f.PC, Fn: f.Func, @@ -28,22 +27,22 @@ func viewerFrames(stk tracev2.Stack) []*trace.Frame { return frames } -func viewerGState(state tracev2.GoState, inMarkAssist bool) traceviewer.GState { +func viewerGState(state trace.GoState, inMarkAssist bool) traceviewer.GState { switch state { - case tracev2.GoUndetermined: + case trace.GoUndetermined: return traceviewer.GDead - case tracev2.GoNotExist: + case trace.GoNotExist: return traceviewer.GDead - case tracev2.GoRunnable: + case trace.GoRunnable: return traceviewer.GRunnable - case tracev2.GoRunning: + case trace.GoRunning: return traceviewer.GRunning - case tracev2.GoWaiting: + case trace.GoWaiting: if inMarkAssist { return traceviewer.GWaitingGC } return traceviewer.GWaiting - case tracev2.GoSyscall: + case trace.GoSyscall: // N.B. A goroutine in a syscall is considered "executing" (state.Executing() == true). return traceviewer.GRunning default: |
