Skip to content

Commit

Permalink
cmd/go/internal/trace: add function to distinguish goroutines
Browse files Browse the repository at this point in the history
trace.StartGoroutine will associate the trace information on the context
with a new chrome profiler thread id. The chrome profiler doesn't
expect multiple trace events to have the same thread id, so this
will allow us to display concurrent events on the trace.

Updates #38714

Change-Id: I81690861df4f444f14f02a99e0fe551395b660a7
Reviewed-on: https://go-review.googlesource.com/c/go/+/238542
Run-TryBot: Michael Matloob <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Jay Conrod <[email protected]>
Reviewed-by: Bryan C. Mills <[email protected]>
  • Loading branch information
matloob committed Aug 12, 2020
1 parent 2bfa45c commit cfbd1c7
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
Binary file added go
Binary file not shown.
27 changes: 24 additions & 3 deletions src/cmd/go/internal/trace/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,33 @@ func StartSpan(ctx context.Context, name string) (context.Context, *Span) {
if !ok {
return ctx, nil
}
childSpan := &Span{t: tc.t, name: name, start: time.Now()}
childSpan := &Span{t: tc.t, name: name, tid: tc.tid, start: time.Now()}
tc.t.writeEvent(&traceviewer.Event{
Name: childSpan.name,
Time: float64(childSpan.start.UnixNano()) / float64(time.Microsecond),
TID: childSpan.tid,
Phase: "B",
})
ctx = context.WithValue(ctx, traceKey{}, traceContext{tc.t})
ctx = context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.tid})
return ctx, childSpan
}

// Goroutine associates the context with a new Thread ID. The Chrome trace viewer associates each
// trace event with a thread, and doesn't expect events with the same thread id to happen at the
// same time.
func Goroutine(ctx context.Context) context.Context {
tc, ok := getTraceContext(ctx)
if !ok {
return ctx
}
return context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.t.getNextTID()})
}

type Span struct {
t *tracer

name string
tid uint64
start time.Time
end time.Time
}
Expand All @@ -59,12 +72,15 @@ func (s *Span) Done() {
s.t.writeEvent(&traceviewer.Event{
Name: s.name,
Time: float64(s.end.UnixNano()) / float64(time.Microsecond),
TID: s.tid,
Phase: "E",
})
}

type tracer struct {
file chan traceFile // 1-buffered

nextTID uint64
}

func (t *tracer) writeEvent(ev *traceviewer.Event) error {
Expand Down Expand Up @@ -102,12 +118,17 @@ func (t *tracer) Close() error {
return firstErr
}

func (t *tracer) getNextTID() uint64 {
return atomic.AddUint64(&t.nextTID, 1)
}

// traceKey is the context key for tracing information. It is unexported to prevent collisions with context keys defined in
// other packages.
type traceKey struct{}

type traceContext struct {
t *tracer
t *tracer
tid uint64
}

// Start starts a trace which writes to the given file.
Expand Down

0 comments on commit cfbd1c7

Please sign in to comment.