if creatorG := s.gs[ev.Goroutine()]; creatorG != nil && len(creatorG.activeRegions) > 0 {
regions := creatorG.activeRegions
s := regions[len(regions)-1]
- if s.TaskID != tracev2.NoTask {
- g.activeRegions = []*UserRegionSummary{{TaskID: s.TaskID, Start: ev}}
- }
+ g.activeRegions = []*UserRegionSummary{{TaskID: s.TaskID, Start: ev}}
}
s.gs[g.ID] = g
case tracev2.GoRunning:
// are of the same type).
type TaskID uint64
-// NoTask indicates the lack of a task.
-const NoTask = TaskID(0)
+const (
+ // NoTask indicates the lack of a task.
+ NoTask = TaskID(^uint64(0))
+
+ // BackgroundTask is the global task that events are attached to if there was
+ // no other task in the context at the point the event was emitted.
+ BackgroundTask = TaskID(0)
+)
// Task provides details about a Task event.
type Task struct {
// Get the parent ID, but don't validate it. There's no guarantee
// we actually have information on whether it's active.
parentID := TaskID(ev.args[1])
+ if parentID == BackgroundTask {
+ // Note: a value of 0 here actually means no parent, *not* the
+ // background task. Automatic background task attachment only
+ // applies to regions.
+ parentID = NoTask
+ ev.args[1] = uint64(NoTask)
+ }
// Validate the name and record it. We'll need to pass it through to
// EvUserTaskEnd.
b1 := g1.Batch(trace.ThreadID(0), 0)
b1.Event("ProcStatus", trace.ProcID(0), go122.ProcRunning)
b1.Event("GoStatus", trace.GoID(1), trace.ThreadID(0), go122.GoRunning)
- b1.Event("UserTaskBegin", trace.TaskID(2), trace.NoTask, "my task", testgen.NoStack)
+ b1.Event("UserTaskBegin", trace.TaskID(2), trace.TaskID(0) /* 0 means no parent, not background */, "my task", testgen.NoStack)
g2 := t.Generation(2)
case trace.EventTaskBegin:
// Validate task begin.
t := ev.Task()
- if t.ID == trace.NoTask {
+ if t.ID == trace.NoTask || t.ID == trace.BackgroundTask {
+ // The background task should never have an event emitted for it.
e.Errorf("found invalid task ID for task of type %s", t.Type)
}
+ if t.Parent == trace.BackgroundTask {
+ // It's not possible for a task to be a subtask of the background task.
+ e.Errorf("found background task as the parent for task of type %s", t.Type)
+ }
// N.B. Don't check the task type. Empty string is a valid task type.
v.tasks[t.ID] = t.Type
case trace.EventTaskEnd:
{trace.EventRegionEnd, trace.TaskID(1), []string{"region0"}},
{trace.EventTaskEnd, trace.TaskID(1), []string{"task0"}},
// Currently, pre-existing region is not recorded to avoid allocations.
- {trace.EventRegionBegin, trace.NoTask, []string{"post-existing region"}},
+ {trace.EventRegionBegin, trace.BackgroundTask, []string{"post-existing region"}},
}
r, err := trace.NewReader(bytes.NewReader(tb))
if err != nil {