Skip to content

Commit 49003da

Browse files
committed
cmd/go/internal/trace: add function to distinguish goroutines
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: I888b0cce15a5a01db66366716fdd85bf86c832cd Reviewed-on: https://go-review.googlesource.com/c/go/+/248319 Run-TryBot: Michael Matloob <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent abfeec5 commit 49003da

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/cmd/go/internal/trace/trace.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,33 @@ func StartSpan(ctx context.Context, name string) (context.Context, *Span) {
3434
if !ok {
3535
return ctx, nil
3636
}
37-
childSpan := &Span{t: tc.t, name: name, start: time.Now()}
37+
childSpan := &Span{t: tc.t, name: name, tid: tc.tid, start: time.Now()}
3838
tc.t.writeEvent(&traceviewer.Event{
3939
Name: childSpan.name,
4040
Time: float64(childSpan.start.UnixNano()) / float64(time.Microsecond),
41+
TID: childSpan.tid,
4142
Phase: "B",
4243
})
43-
ctx = context.WithValue(ctx, traceKey{}, traceContext{tc.t})
44+
ctx = context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.tid})
4445
return ctx, childSpan
4546
}
4647

48+
// Goroutine associates the context with a new Thread ID. The Chrome trace viewer associates each
49+
// trace event with a thread, and doesn't expect events with the same thread id to happen at the
50+
// same time.
51+
func Goroutine(ctx context.Context) context.Context {
52+
tc, ok := getTraceContext(ctx)
53+
if !ok {
54+
return ctx
55+
}
56+
return context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.t.getNextTID()})
57+
}
58+
4759
type Span struct {
4860
t *tracer
4961

5062
name string
63+
tid uint64
5164
start time.Time
5265
end time.Time
5366
}
@@ -60,12 +73,15 @@ func (s *Span) Done() {
6073
s.t.writeEvent(&traceviewer.Event{
6174
Name: s.name,
6275
Time: float64(s.end.UnixNano()) / float64(time.Microsecond),
76+
TID: s.tid,
6377
Phase: "E",
6478
})
6579
}
6680

6781
type tracer struct {
6882
file chan traceFile // 1-buffered
83+
84+
nextTID uint64
6985
}
7086

7187
func (t *tracer) writeEvent(ev *traceviewer.Event) error {
@@ -103,12 +119,17 @@ func (t *tracer) Close() error {
103119
return firstErr
104120
}
105121

122+
func (t *tracer) getNextTID() uint64 {
123+
return atomic.AddUint64(&t.nextTID, 1)
124+
}
125+
106126
// traceKey is the context key for tracing information. It is unexported to prevent collisions with context keys defined in
107127
// other packages.
108128
type traceKey struct{}
109129

110130
type traceContext struct {
111-
t *tracer
131+
t *tracer
132+
tid uint64
112133
}
113134

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

0 commit comments

Comments
 (0)