aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/trace/annotations.go204
-rw-r--r--src/cmd/trace/annotations_test.go110
-rw-r--r--src/cmd/trace/main.go2
-rw-r--r--src/cmd/trace/pprof.go34
-rw-r--r--src/cmd/trace/trace.go24
5 files changed, 187 insertions, 187 deletions
diff --git a/src/cmd/trace/annotations.go b/src/cmd/trace/annotations.go
index 0d2bdfcbba..5f672de3b4 100644
--- a/src/cmd/trace/annotations.go
+++ b/src/cmd/trace/annotations.go
@@ -18,8 +18,8 @@ import (
func init() {
http.HandleFunc("/usertasks", httpUserTasks)
http.HandleFunc("/usertask", httpUserTask)
- http.HandleFunc("/userspans", httpUserSpans)
- http.HandleFunc("/userspan", httpUserSpan)
+ http.HandleFunc("/userregions", httpUserRegions)
+ http.HandleFunc("/userregion", httpUserRegion)
}
// httpUserTasks reports all tasks found in the trace.
@@ -59,46 +59,46 @@ func httpUserTasks(w http.ResponseWriter, r *http.Request) {
}
}
-func httpUserSpans(w http.ResponseWriter, r *http.Request) {
+func httpUserRegions(w http.ResponseWriter, r *http.Request) {
res, err := analyzeAnnotations()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- allSpans := res.spans
+ allRegions := res.regions
- summary := make(map[spanTypeID]spanStats)
- for id, spans := range allSpans {
+ summary := make(map[regionTypeID]regionStats)
+ for id, regions := range allRegions {
stats, ok := summary[id]
if !ok {
- stats.spanTypeID = id
+ stats.regionTypeID = id
}
- for _, s := range spans {
+ for _, s := range regions {
stats.add(s)
}
summary[id] = stats
}
- // Sort spans by pc and name
- userSpans := make([]spanStats, 0, len(summary))
+ // Sort regions by pc and name
+ userRegions := make([]regionStats, 0, len(summary))
for _, stats := range summary {
- userSpans = append(userSpans, stats)
+ userRegions = append(userRegions, stats)
}
- sort.Slice(userSpans, func(i, j int) bool {
- if userSpans[i].Type != userSpans[j].Type {
- return userSpans[i].Type < userSpans[j].Type
+ sort.Slice(userRegions, func(i, j int) bool {
+ if userRegions[i].Type != userRegions[j].Type {
+ return userRegions[i].Type < userRegions[j].Type
}
- return userSpans[i].Frame.PC < userSpans[j].Frame.PC
+ return userRegions[i].Frame.PC < userRegions[j].Frame.PC
})
// Emit table.
- err = templUserSpanTypes.Execute(w, userSpans)
+ err = templUserRegionTypes.Execute(w, userRegions)
if err != nil {
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
return
}
}
-func httpUserSpan(w http.ResponseWriter, r *http.Request) {
- filter, err := newSpanFilter(r)
+func httpUserRegion(w http.ResponseWriter, r *http.Request) {
+ filter, err := newRegionFilter(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@@ -108,13 +108,13 @@ func httpUserSpan(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- allSpans := res.spans
+ allRegions := res.regions
- var data []spanDesc
+ var data []regionDesc
var maxTotal int64
- for id, spans := range allSpans {
- for _, s := range spans {
+ for id, regions := range allRegions {
+ for _, s := range regions {
if !filter.match(id, s) {
continue
}
@@ -126,7 +126,7 @@ func httpUserSpan(w http.ResponseWriter, r *http.Request) {
}
sortby := r.FormValue("sortby")
- _, ok := reflect.TypeOf(spanDesc{}).FieldByNameFunc(func(s string) bool {
+ _, ok := reflect.TypeOf(regionDesc{}).FieldByNameFunc(func(s string) bool {
return s == sortby
})
if !ok {
@@ -138,9 +138,9 @@ func httpUserSpan(w http.ResponseWriter, r *http.Request) {
return ival > jval
})
- err = templUserSpanType.Execute(w, struct {
+ err = templUserRegionType.Execute(w, struct {
MaxTotal int64
- Data []spanDesc
+ Data []regionDesc
Name string
}{
MaxTotal: maxTotal,
@@ -193,9 +193,9 @@ func httpUserTask(w http.ResponseWriter, r *http.Request) {
if !filter.match(task) {
continue
}
- // merge events in the task.events and task.spans.Start
+ // merge events in the task.events and task.regions.Start
rawEvents := append([]*trace.Event{}, task.events...)
- for _, s := range task.spans {
+ for _, s := range task.regions {
if s.Start != nil {
rawEvents = append(rawEvents, s.Start)
}
@@ -254,12 +254,12 @@ func httpUserTask(w http.ResponseWriter, r *http.Request) {
}
type annotationAnalysisResult struct {
- tasks map[uint64]*taskDesc // tasks
- spans map[spanTypeID][]spanDesc // spans
- gcEvents []*trace.Event // GCStartevents, sorted
+ tasks map[uint64]*taskDesc // tasks
+ regions map[regionTypeID][]regionDesc // regions
+ gcEvents []*trace.Event // GCStartevents, sorted
}
-type spanTypeID struct {
+type regionTypeID struct {
Frame trace.Frame // top frame
Type string
}
@@ -278,7 +278,7 @@ func analyzeAnnotations() (annotationAnalysisResult, error) {
}
tasks := allTasks{}
- spans := map[spanTypeID][]spanDesc{}
+ regions := map[regionTypeID][]regionDesc{}
var gcEvents []*trace.Event
for _, ev := range events {
@@ -303,38 +303,38 @@ func analyzeAnnotations() (annotationAnalysisResult, error) {
gcEvents = append(gcEvents, ev)
}
}
- // combine span info.
+ // combine region info.
analyzeGoroutines(events)
for goid, stats := range gs {
// gs is a global var defined in goroutines.go as a result
// of analyzeGoroutines. TODO(hyangah): fix this not to depend
// on a 'global' var.
- for _, s := range stats.Spans {
+ for _, s := range stats.Regions {
if s.TaskID != 0 {
task := tasks.task(s.TaskID)
task.goroutines[goid] = struct{}{}
- task.spans = append(task.spans, spanDesc{UserSpanDesc: s, G: goid})
+ task.regions = append(task.regions, regionDesc{UserRegionDesc: s, G: goid})
}
var frame trace.Frame
if s.Start != nil {
frame = *s.Start.Stk[0]
}
- id := spanTypeID{Frame: frame, Type: s.Name}
- spans[id] = append(spans[id], spanDesc{UserSpanDesc: s, G: goid})
+ id := regionTypeID{Frame: frame, Type: s.Name}
+ regions[id] = append(regions[id], regionDesc{UserRegionDesc: s, G: goid})
}
}
- // sort spans in tasks based on the timestamps.
+ // sort regions in tasks based on the timestamps.
for _, task := range tasks {
- sort.SliceStable(task.spans, func(i, j int) bool {
- si, sj := task.spans[i].firstTimestamp(), task.spans[j].firstTimestamp()
+ sort.SliceStable(task.regions, func(i, j int) bool {
+ si, sj := task.regions[i].firstTimestamp(), task.regions[j].firstTimestamp()
if si != sj {
return si < sj
}
- return task.spans[i].lastTimestamp() < task.spans[i].lastTimestamp()
+ return task.regions[i].lastTimestamp() < task.regions[i].lastTimestamp()
})
}
- return annotationAnalysisResult{tasks: tasks, spans: spans, gcEvents: gcEvents}, nil
+ return annotationAnalysisResult{tasks: tasks, regions: regions, gcEvents: gcEvents}, nil
}
// taskDesc represents a task.
@@ -342,7 +342,7 @@ type taskDesc struct {
name string // user-provided task name
id uint64 // internal task id
events []*trace.Event // sorted based on timestamp.
- spans []spanDesc // associated spans, sorted based on the start timestamp and then the last timestamp.
+ regions []regionDesc // associated regions, sorted based on the start timestamp and then the last timestamp.
goroutines map[uint64]struct{} // involved goroutines
create *trace.Event // Task create event
@@ -367,8 +367,8 @@ func (task *taskDesc) String() string {
fmt.Fprintf(wb, "task %d:\t%s\n", task.id, task.name)
fmt.Fprintf(wb, "\tstart: %v end: %v complete: %t\n", task.firstTimestamp(), task.lastTimestamp(), task.complete())
fmt.Fprintf(wb, "\t%d goroutines\n", len(task.goroutines))
- fmt.Fprintf(wb, "\t%d spans:\n", len(task.spans))
- for _, s := range task.spans {
+ fmt.Fprintf(wb, "\t%d regions:\n", len(task.regions))
+ for _, s := range task.regions {
fmt.Fprintf(wb, "\t\t%s(goid=%d)\n", s.Name, s.G)
}
if task.parent != nil {
@@ -382,10 +382,10 @@ func (task *taskDesc) String() string {
return wb.String()
}
-// spanDesc represents a span.
-type spanDesc struct {
- *trace.UserSpanDesc
- G uint64 // id of goroutine where the span was defined
+// regionDesc represents a region.
+type regionDesc struct {
+ *trace.UserRegionDesc
+ G uint64 // id of goroutine where the region was defined
}
type allTasks map[uint64]*taskDesc
@@ -473,8 +473,8 @@ func (task *taskDesc) duration() time.Duration {
return time.Duration(task.lastTimestamp()-task.firstTimestamp()) * time.Nanosecond
}
-func (span *spanDesc) duration() time.Duration {
- return time.Duration(span.lastTimestamp()-span.firstTimestamp()) * time.Nanosecond
+func (region *regionDesc) duration() time.Duration {
+ return time.Duration(region.lastTimestamp()-region.firstTimestamp()) * time.Nanosecond
}
// overlappingGCDuration returns the sum of GC period overlapping with the task's lifetime.
@@ -493,7 +493,7 @@ func (task *taskDesc) overlappingGCDuration(evs []*trace.Event) (overlapping tim
}
// overlappingInstant returns true if the instantaneous event, ev, occurred during
-// any of the task's span if ev is a goroutine-local event, or overlaps with the
+// any of the task's region if ev is a goroutine-local event, or overlaps with the
// task's lifetime if ev is a global event.
func (task *taskDesc) overlappingInstant(ev *trace.Event) bool {
if isUserAnnotationEvent(ev) && task.id != ev.Args[0] {
@@ -510,13 +510,13 @@ func (task *taskDesc) overlappingInstant(ev *trace.Event) bool {
return true
}
- // Goroutine local event. Check whether there are spans overlapping with the event.
+ // Goroutine local event. Check whether there are regions overlapping with the event.
goid := ev.G
- for _, span := range task.spans {
- if span.G != goid {
+ for _, region := range task.regions {
+ if region.G != goid {
continue
}
- if span.firstTimestamp() <= ts && ts <= span.lastTimestamp() {
+ if region.firstTimestamp() <= ts && ts <= region.lastTimestamp() {
return true
}
}
@@ -524,7 +524,7 @@ func (task *taskDesc) overlappingInstant(ev *trace.Event) bool {
}
// overlappingDuration returns whether the durational event, ev, overlaps with
-// any of the task's span if ev is a goroutine-local event, or overlaps with
+// any of the task's region if ev is a goroutine-local event, or overlaps with
// the task's lifetime if ev is a global event. It returns the overlapping time
// as well.
func (task *taskDesc) overlappingDuration(ev *trace.Event) (time.Duration, bool) {
@@ -552,21 +552,21 @@ func (task *taskDesc) overlappingDuration(ev *trace.Event) (time.Duration, bool)
return o, o > 0
}
- // Goroutine local event. Check whether there are spans overlapping with the event.
+ // Goroutine local event. Check whether there are regions overlapping with the event.
var overlapping time.Duration
- var lastSpanEnd int64 // the end of previous overlapping span
- for _, span := range task.spans {
- if span.G != goid && span.G != goid2 {
+ var lastRegionEnd int64 // the end of previous overlapping region
+ for _, region := range task.regions {
+ if region.G != goid && region.G != goid2 {
continue
}
- spanStart, spanEnd := span.firstTimestamp(), span.lastTimestamp()
- if spanStart < lastSpanEnd { // skip nested spans
+ regionStart, regionEnd := region.firstTimestamp(), region.lastTimestamp()
+ if regionStart < lastRegionEnd { // skip nested regions
continue
}
- if o := overlappingDuration(spanStart, spanEnd, start, end); o > 0 {
+ if o := overlappingDuration(regionStart, regionEnd, start, end); o > 0 {
// overlapping.
- lastSpanEnd = spanEnd
+ lastRegionEnd = regionEnd
overlapping += o
}
}
@@ -602,22 +602,22 @@ func (task *taskDesc) lastEvent() *trace.Event {
return nil
}
-// firstTimestamp returns the timestamp of span start event.
-// If the span's start event is not present in the trace,
+// firstTimestamp returns the timestamp of region start event.
+// If the region's start event is not present in the trace,
// the first timestamp of the trace will be returned.
-func (span *spanDesc) firstTimestamp() int64 {
- if span.Start != nil {
- return span.Start.Ts
+func (region *regionDesc) firstTimestamp() int64 {
+ if region.Start != nil {
+ return region.Start.Ts
}
return firstTimestamp()
}
-// lastTimestamp returns the timestamp of span end event.
-// If the span's end event is not present in the trace,
+// lastTimestamp returns the timestamp of region end event.
+// If the region's end event is not present in the trace,
// the last timestamp of the trace will be returned.
-func (span *spanDesc) lastTimestamp() int64 {
- if span.End != nil {
- return span.End.Ts
+func (region *regionDesc) lastTimestamp() int64 {
+ if region.End != nil {
+ return region.End.Ts
}
return lastTimestamp()
}
@@ -721,7 +721,7 @@ func newTaskFilter(r *http.Request) (*taskFilter, error) {
func taskMatches(t *taskDesc, text string) bool {
for _, ev := range t.events {
switch ev.Type {
- case trace.EvUserTaskCreate, trace.EvUserSpan, trace.EvUserLog:
+ case trace.EvUserTaskCreate, trace.EvUserRegion, trace.EvUserLog:
for _, s := range ev.SArgs {
if strings.Contains(s, text) {
return true
@@ -732,12 +732,12 @@ func taskMatches(t *taskDesc, text string) bool {
return false
}
-type spanFilter struct {
+type regionFilter struct {
name string
- cond []func(spanTypeID, spanDesc) bool
+ cond []func(regionTypeID, regionDesc) bool
}
-func (f *spanFilter) match(id spanTypeID, s spanDesc) bool {
+func (f *regionFilter) match(id regionTypeID, s regionDesc) bool {
for _, c := range f.cond {
if !c(id, s) {
return false
@@ -746,42 +746,42 @@ func (f *spanFilter) match(id spanTypeID, s spanDesc) bool {
return true
}
-func newSpanFilter(r *http.Request) (*spanFilter, error) {
+func newRegionFilter(r *http.Request) (*regionFilter, error) {
if err := r.ParseForm(); err != nil {
return nil, err
}
var name []string
- var conditions []func(spanTypeID, spanDesc) bool
+ var conditions []func(regionTypeID, regionDesc) bool
param := r.Form
if typ, ok := param["type"]; ok && len(typ) > 0 {
name = append(name, "type="+typ[0])
- conditions = append(conditions, func(id spanTypeID, s spanDesc) bool {
+ conditions = append(conditions, func(id regionTypeID, s regionDesc) bool {
return id.Type == typ[0]
})
}
if pc, err := strconv.ParseUint(r.FormValue("pc"), 16, 64); err == nil {
name = append(name, fmt.Sprintf("pc=%x", pc))
- conditions = append(conditions, func(id spanTypeID, s spanDesc) bool {
+ conditions = append(conditions, func(id regionTypeID, s regionDesc) bool {
return id.Frame.PC == pc
})
}
if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil {
name = append(name, fmt.Sprintf("latency >= %s", lat))
- conditions = append(conditions, func(_ spanTypeID, s spanDesc) bool {
+ conditions = append(conditions, func(_ regionTypeID, s regionDesc) bool {
return s.duration() >= lat
})
}
if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil {
name = append(name, fmt.Sprintf("latency <= %s", lat))
- conditions = append(conditions, func(_ spanTypeID, s spanDesc) bool {
+ conditions = append(conditions, func(_ regionTypeID, s regionDesc) bool {
return s.duration() <= lat
})
}
- return &spanFilter{name: strings.Join(name, ","), cond: conditions}, nil
+ return &regionFilter{name: strings.Join(name, ","), cond: conditions}, nil
}
type durationHistogram struct {
@@ -893,22 +893,22 @@ func (h *durationHistogram) String() string {
return w.String()
}
-type spanStats struct {
- spanTypeID
+type regionStats struct {
+ regionTypeID
Histogram durationHistogram
}
-func (s *spanStats) UserSpanURL() func(min, max time.Duration) string {
+func (s *regionStats) UserRegionURL() func(min, max time.Duration) string {
return func(min, max time.Duration) string {
- return fmt.Sprintf("/userspan?type=%s&pc=%x&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), s.Frame.PC, template.URLQueryEscaper(min), template.URLQueryEscaper(max))
+ return fmt.Sprintf("/userregion?type=%s&pc=%x&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), s.Frame.PC, template.URLQueryEscaper(min), template.URLQueryEscaper(max))
}
}
-func (s *spanStats) add(span spanDesc) {
- s.Histogram.add(span.duration())
+func (s *regionStats) add(region regionDesc) {
+ s.Histogram.add(region.duration())
}
-var templUserSpanTypes = template.Must(template.New("").Parse(`
+var templUserRegionTypes = template.Must(template.New("").Parse(`
<html>
<style type="text/css">
.histoTime {
@@ -920,15 +920,15 @@ var templUserSpanTypes = template.Must(template.New("").Parse(`
<body>
<table border="1" sortable="1">
<tr>
-<th>Span type</th>
+<th>Region type</th>
<th>Count</th>
<th>Duration distribution (complete tasks)</th>
</tr>
{{range $}}
<tr>
<td>{{.Type}}<br>{{.Frame.Fn}}<br>{{.Frame.File}}:{{.Frame.Line}}</td>
- <td><a href="/userspan?type={{.Type}}&pc={{.Frame.PC}}">{{.Histogram.Count}}</a></td>
- <td>{{.Histogram.ToHTML (.UserSpanURL)}}</td>
+ <td><a href="/userregion?type={{.Type}}&pc={{.Frame.PC}}">{{.Histogram.Count}}</a></td>
+ <td>{{.Histogram.ToHTML (.UserRegionURL)}}</td>
</tr>
{{end}}
</table>
@@ -1109,15 +1109,15 @@ func describeEvent(ev *trace.Event) string {
return "goroutine stopped"
case trace.EvUserLog:
return formatUserLog(ev)
- case trace.EvUserSpan:
+ case trace.EvUserRegion:
if ev.Args[1] == 0 {
duration := "unknown"
if ev.Link != nil {
duration = (time.Duration(ev.Link.Ts-ev.Ts) * time.Nanosecond).String()
}
- return fmt.Sprintf("span %s started (duration: %v)", ev.SArgs[0], duration)
+ return fmt.Sprintf("region %s started (duration: %v)", ev.SArgs[0], duration)
}
- return fmt.Sprintf("span %s ended", ev.SArgs[0])
+ return fmt.Sprintf("region %s ended", ev.SArgs[0])
case trace.EvUserTaskCreate:
return fmt.Sprintf("task %v (id %d, parent %d) created", ev.SArgs[0], ev.Args[0], ev.Args[1])
// TODO: add child task creation events into the parent task events
@@ -1129,13 +1129,13 @@ func describeEvent(ev *trace.Event) string {
func isUserAnnotationEvent(ev *trace.Event) bool {
switch ev.Type {
- case trace.EvUserLog, trace.EvUserSpan, trace.EvUserTaskCreate, trace.EvUserTaskEnd:
+ case trace.EvUserLog, trace.EvUserRegion, trace.EvUserTaskCreate, trace.EvUserTaskEnd:
return true
}
return false
}
-var templUserSpanType = template.Must(template.New("").Funcs(template.FuncMap{
+var templUserRegionType = template.Must(template.New("").Funcs(template.FuncMap{
"prettyDuration": func(nsec int64) template.HTML {
d := time.Duration(nsec) * time.Nanosecond
return template.HTML(niceDuration(d))
@@ -1152,7 +1152,7 @@ var templUserSpanType = template.Must(template.New("").Funcs(template.FuncMap{
}
return template.HTML(fmt.Sprintf("%.2f%%", float64(dividened)/float64(divisor)*100))
},
- "unknownTime": func(desc spanDesc) int64 {
+ "unknownTime": func(desc regionDesc) int64 {
sum := desc.ExecTime + desc.IOTime + desc.BlockTime + desc.SyscallTime + desc.SchedWaitTime
if sum < desc.TotalTime {
return desc.TotalTime - sum
diff --git a/src/cmd/trace/annotations_test.go b/src/cmd/trace/annotations_test.go
index 96b83734d7..5d2b226b35 100644
--- a/src/cmd/trace/annotations_test.go
+++ b/src/cmd/trace/annotations_test.go
@@ -47,9 +47,9 @@ func TestOverlappingDuration(t *testing.T) {
// prog0 starts three goroutines.
//
-// goroutine 1: taskless span
-// goroutine 2: starts task0, do work in task0.span0, starts task1 which ends immediately.
-// goroutine 3: do work in task0.span1 and task0.span2, ends task0
+// goroutine 1: taskless region
+// goroutine 2: starts task0, do work in task0.region0, starts task1 which ends immediately.
+// goroutine 3: do work in task0.region1 and task0.region2, ends task0
func prog0() {
ctx := context.Background()
@@ -58,7 +58,7 @@ func prog0() {
wg.Add(1)
go func() { // goroutine 1
defer wg.Done()
- trace.WithSpan(ctx, "taskless.span", func(ctx context.Context) {
+ trace.WithRegion(ctx, "taskless.region", func() {
trace.Log(ctx, "key0", "val0")
})
}()
@@ -66,29 +66,29 @@ func prog0() {
wg.Add(1)
go func() { // goroutine 2
defer wg.Done()
- ctx, taskDone := trace.NewContext(ctx, "task0")
- trace.WithSpan(ctx, "task0.span0", func(ctx context.Context) {
+ ctx, task := trace.NewTask(ctx, "task0")
+ trace.WithRegion(ctx, "task0.region0", func() {
wg.Add(1)
go func() { // goroutine 3
defer wg.Done()
- defer taskDone()
- trace.WithSpan(ctx, "task0.span1", func(ctx context.Context) {
- trace.WithSpan(ctx, "task0.span2", func(ctx context.Context) {
+ defer task.End()
+ trace.WithRegion(ctx, "task0.region1", func() {
+ trace.WithRegion(ctx, "task0.region2", func() {
trace.Log(ctx, "key2", "val2")
})
trace.Log(ctx, "key1", "val1")
})
}()
})
- ctx2, taskDone2 := trace.NewContext(ctx, "task1")
+ ctx2, task2 := trace.NewTask(ctx, "task1")
trace.Log(ctx2, "key3", "val3")
- taskDone2()
+ task2.End()
}()
wg.Wait()
}
func TestAnalyzeAnnotations(t *testing.T) {
- // TODO: classify taskless spans
+ // TODO: classify taskless regions
// Run prog0 and capture the execution trace.
if err := traceProgram(t, prog0, "TestAnalyzeAnnotations"); err != nil {
@@ -101,17 +101,17 @@ func TestAnalyzeAnnotations(t *testing.T) {
}
// For prog0, we expect
- // - task with name = "task0", with three spans.
- // - task with name = "task1", with no span.
+ // - task with name = "task0", with three regions.
+ // - task with name = "task1", with no region.
wantTasks := map[string]struct {
complete bool
goroutines int
- spans []string
+ regions []string
}{
"task0": {
complete: true,
goroutines: 2,
- spans: []string{"task0.span0", "", "task0.span1", "task0.span2"},
+ regions: []string{"task0.region0", "", "task0.region1", "task0.region2"},
},
"task1": {
complete: true,
@@ -125,7 +125,7 @@ func TestAnalyzeAnnotations(t *testing.T) {
t.Errorf("unexpected task: %s", task)
continue
}
- if task.complete() != want.complete || len(task.goroutines) != want.goroutines || !reflect.DeepEqual(spanNames(task), want.spans) {
+ if task.complete() != want.complete || len(task.goroutines) != want.goroutines || !reflect.DeepEqual(regionNames(task), want.regions) {
t.Errorf("got task %v; want %+v", task, want)
}
@@ -135,37 +135,37 @@ func TestAnalyzeAnnotations(t *testing.T) {
t.Errorf("no more tasks; want %+v", wantTasks)
}
- wantSpans := []string{
- "", // an auto-created span for the goroutine 3
- "taskless.span",
- "task0.span0",
- "task0.span1",
- "task0.span2",
+ wantRegions := []string{
+ "", // an auto-created region for the goroutine 3
+ "taskless.region",
+ "task0.region0",
+ "task0.region1",
+ "task0.region2",
}
- var gotSpans []string
- for spanID := range res.spans {
- gotSpans = append(gotSpans, spanID.Type)
+ var gotRegions []string
+ for regionID := range res.regions {
+ gotRegions = append(gotRegions, regionID.Type)
}
- sort.Strings(wantSpans)
- sort.Strings(gotSpans)
- if !reflect.DeepEqual(gotSpans, wantSpans) {
- t.Errorf("got spans %q, want spans %q", gotSpans, wantSpans)
+ sort.Strings(wantRegions)
+ sort.Strings(gotRegions)
+ if !reflect.DeepEqual(gotRegions, wantRegions) {
+ t.Errorf("got regions %q, want regions %q", gotRegions, wantRegions)
}
}
// prog1 creates a task hierarchy consisting of three tasks.
func prog1() {
ctx := context.Background()
- ctx1, done1 := trace.NewContext(ctx, "task1")
- defer done1()
- trace.WithSpan(ctx1, "task1.span", func(ctx context.Context) {
- ctx2, done2 := trace.NewContext(ctx, "task2")
- defer done2()
- trace.WithSpan(ctx2, "task2.span", func(ctx context.Context) {
- ctx3, done3 := trace.NewContext(ctx, "task3")
- defer done3()
- trace.WithSpan(ctx3, "task3.span", func(ctx context.Context) {
+ ctx1, task1 := trace.NewTask(ctx, "task1")
+ defer task1.End()
+ trace.WithRegion(ctx1, "task1.region", func() {
+ ctx2, task2 := trace.NewTask(ctx1, "task2")
+ defer task2.End()
+ trace.WithRegion(ctx2, "task2.region", func() {
+ ctx3, task3 := trace.NewTask(ctx2, "task3")
+ defer task3.End()
+ trace.WithRegion(ctx3, "task3.region", func() {
})
})
})
@@ -184,27 +184,27 @@ func TestAnalyzeAnnotationTaskTree(t *testing.T) {
tasks := res.tasks
// For prog0, we expect
- // - task with name = "", with taskless.span in spans.
- // - task with name = "task0", with three spans.
+ // - task with name = "", with taskless.region in regions.
+ // - task with name = "task0", with three regions.
wantTasks := map[string]struct {
parent string
children []string
- spans []string
+ regions []string
}{
"task1": {
parent: "",
children: []string{"task2"},
- spans: []string{"task1.span"},
+ regions: []string{"task1.region"},
},
"task2": {
parent: "task1",
children: []string{"task3"},
- spans: []string{"task2.span"},
+ regions: []string{"task2.region"},
},
"task3": {
parent: "task2",
children: nil,
- spans: []string{"task3.span"},
+ regions: []string{"task3.region"},
},
}
@@ -218,7 +218,7 @@ func TestAnalyzeAnnotationTaskTree(t *testing.T) {
if parentName(task) != want.parent ||
!reflect.DeepEqual(childrenNames(task), want.children) ||
- !reflect.DeepEqual(spanNames(task), want.spans) {
+ !reflect.DeepEqual(regionNames(task), want.regions) {
t.Errorf("got %v; want %+v", task, want)
}
}
@@ -234,10 +234,10 @@ func TestAnalyzeAnnotationTaskTree(t *testing.T) {
// prog2 returns the upper-bound gc time that overlaps with the first task.
func prog2() (gcTime time.Duration) {
ch := make(chan bool)
- ctx1, done := trace.NewContext(context.Background(), "taskWithGC")
- trace.WithSpan(ctx1, "taskWithGC.span1", func(ctx context.Context) {
+ ctx1, task := trace.NewTask(context.Background(), "taskWithGC")
+ trace.WithRegion(ctx1, "taskWithGC.region1", func() {
go func() {
- defer trace.StartSpan(ctx, "taskWithGC.span2")()
+ defer trace.StartRegion(ctx1, "taskWithGC.region2").End()
<-ch
}()
s := time.Now()
@@ -245,13 +245,13 @@ func prog2() (gcTime time.Duration) {
gcTime = time.Since(s)
close(ch)
})
- done()
+ task.End()
- ctx2, done2 := trace.NewContext(context.Background(), "taskWithoutGC")
- trace.WithSpan(ctx2, "taskWithoutGC.span1", func(ctx context.Context) {
+ ctx2, task2 := trace.NewTask(context.Background(), "taskWithoutGC")
+ trace.WithRegion(ctx2, "taskWithoutGC.region1", func() {
// do nothing.
})
- done2()
+ task2.End()
return gcTime
}
@@ -343,8 +343,8 @@ func traceProgram(t *testing.T, f func(), name string) error {
return nil
}
-func spanNames(task *taskDesc) (ret []string) {
- for _, s := range task.spans {
+func regionNames(task *taskDesc) (ret []string) {
+ for _, s := range task.regions {
ret = append(ret, s.Name)
}
return ret
diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go
index 57608067f1..0c98b85c37 100644
--- a/src/cmd/trace/main.go
+++ b/src/cmd/trace/main.go
@@ -200,7 +200,7 @@ var templMain = template.Must(template.New("").Parse(`
<a href="/syscall">Syscall blocking profile</a> (<a href="/syscall?raw=1" download="syscall.profile">⬇</a>)<br>
<a href="/sched">Scheduler latency profile</a> (<a href="/sche?raw=1" download="sched.profile">⬇</a>)<br>
<a href="/usertasks">User-defined tasks</a><br>
-<a href="/userspans">User-defined spans</a><br>
+<a href="/userregions">User-defined regions</a><br>
</body>
</html>
`))
diff --git a/src/cmd/trace/pprof.go b/src/cmd/trace/pprof.go
index c0972f2b46..3389d2799b 100644
--- a/src/cmd/trace/pprof.go
+++ b/src/cmd/trace/pprof.go
@@ -42,10 +42,10 @@ func init() {
http.HandleFunc("/syscall", serveSVGProfile(pprofByGoroutine(computePprofSyscall)))
http.HandleFunc("/sched", serveSVGProfile(pprofByGoroutine(computePprofSched)))
- http.HandleFunc("/spanio", serveSVGProfile(pprofBySpan(computePprofIO)))
- http.HandleFunc("/spanblock", serveSVGProfile(pprofBySpan(computePprofBlock)))
- http.HandleFunc("/spansyscall", serveSVGProfile(pprofBySpan(computePprofSyscall)))
- http.HandleFunc("/spansched", serveSVGProfile(pprofBySpan(computePprofSched)))
+ http.HandleFunc("/regionio", serveSVGProfile(pprofByRegion(computePprofIO)))
+ http.HandleFunc("/regionblock", serveSVGProfile(pprofByRegion(computePprofBlock)))
+ http.HandleFunc("/regionsyscall", serveSVGProfile(pprofByRegion(computePprofSyscall)))
+ http.HandleFunc("/regionsched", serveSVGProfile(pprofByRegion(computePprofSched)))
}
// Record represents one entry in pprof-like profiles.
@@ -75,13 +75,13 @@ func pprofByGoroutine(compute func(io.Writer, map[uint64][]interval, []*trace.Ev
}
}
-func pprofBySpan(compute func(io.Writer, map[uint64][]interval, []*trace.Event) error) func(w io.Writer, r *http.Request) error {
+func pprofByRegion(compute func(io.Writer, map[uint64][]interval, []*trace.Event) error) func(w io.Writer, r *http.Request) error {
return func(w io.Writer, r *http.Request) error {
- filter, err := newSpanFilter(r)
+ filter, err := newRegionFilter(r)
if err != nil {
return err
}
- gToIntervals, err := pprofMatchingSpans(filter)
+ gToIntervals, err := pprofMatchingRegions(filter)
if err != nil {
return err
}
@@ -123,9 +123,9 @@ func pprofMatchingGoroutines(id string, events []*trace.Event) (map[uint64][]int
return res, nil
}
-// pprofMatchingSpans returns the time intervals of matching spans
+// pprofMatchingRegions returns the time intervals of matching regions
// grouped by the goroutine id. If the filter is nil, returns nil without an error.
-func pprofMatchingSpans(filter *spanFilter) (map[uint64][]interval, error) {
+func pprofMatchingRegions(filter *regionFilter) (map[uint64][]interval, error) {
res, err := analyzeAnnotations()
if err != nil {
return nil, err
@@ -135,8 +135,8 @@ func pprofMatchingSpans(filter *spanFilter) (map[uint64][]interval, error) {
}
gToIntervals := make(map[uint64][]interval)
- for id, spans := range res.spans {
- for _, s := range spans {
+ for id, regions := range res.regions {
+ for _, s := range regions {
if filter.match(id, s) {
gToIntervals[s.G] = append(gToIntervals[s.G], interval{begin: s.firstTimestamp(), end: s.lastTimestamp()})
}
@@ -144,10 +144,10 @@ func pprofMatchingSpans(filter *spanFilter) (map[uint64][]interval, error) {
}
for g, intervals := range gToIntervals {
- // in order to remove nested spans and
- // consider only the outermost spans,
+ // in order to remove nested regions and
+ // consider only the outermost regions,
// first, we sort based on the start time
- // and then scan through to select only the outermost spans.
+ // and then scan through to select only the outermost regions.
sort.Slice(intervals, func(i, j int) bool {
x := intervals[i].begin
y := intervals[j].begin
@@ -158,13 +158,13 @@ func pprofMatchingSpans(filter *spanFilter) (map[uint64][]interval, error) {
})
var lastTimestamp int64
var n int
- // select only the outermost spans.
+ // select only the outermost regions.
for _, i := range intervals {
if lastTimestamp <= i.begin {
- intervals[n] = i // new non-overlapping span starts.
+ intervals[n] = i // new non-overlapping region starts.
lastTimestamp = i.end
n++
- } // otherwise, skip because this span overlaps with a previous span.
+ } // otherwise, skip because this region overlaps with a previous region.
}
gToIntervals[g] = intervals[:n]
}
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index e3bb40614d..19d6fa36a7 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -405,7 +405,7 @@ type traceContext struct {
threadStats, prevThreadStats threadStats
gstates, prevGstates [gStateCount]int64
- spanID int // last emitted span id. incremented in each emitSpan call.
+ regionID int // last emitted region id. incremented in each emitRegion call.
}
type heapStats struct {
@@ -738,7 +738,7 @@ func generateTrace(params *traceParams, consumer traceConsumer) error {
}
}
- // Display task and its spans if we are in task-oriented presentation mode.
+ // Display task and its regions if we are in task-oriented presentation mode.
if ctx.mode&modeTaskOriented != 0 {
taskRow := uint64(trace.GCP + 1)
for _, task := range ctx.tasks {
@@ -757,11 +757,11 @@ func generateTrace(params *traceParams, consumer traceConsumer) error {
}
ctx.emit(tEnd)
- // If we are in goroutine-oriented mode, we draw spans.
+ // If we are in goroutine-oriented mode, we draw regions.
// TODO(hyangah): add this for task/P-oriented mode (i.e., focustask view) too.
if ctx.mode&modeGoroutineOriented != 0 {
- for _, s := range task.spans {
- ctx.emitSpan(s)
+ for _, s := range task.regions {
+ ctx.emitRegion(s)
}
}
}
@@ -859,23 +859,23 @@ func (ctx *traceContext) emitSlice(ev *trace.Event, name string) *ViewerEvent {
return sl
}
-func (ctx *traceContext) emitSpan(s spanDesc) {
+func (ctx *traceContext) emitRegion(s regionDesc) {
if s.Name == "" {
return
}
- ctx.spanID++
- spanID := ctx.spanID
+ ctx.regionID++
+ regionID := ctx.regionID
id := s.TaskID
scopeID := fmt.Sprintf("%x", id)
sl0 := &ViewerEvent{
- Category: "Span",
+ Category: "Region",
Name: s.Name,
Phase: "b",
Time: float64(s.firstTimestamp()) / 1e3,
Tid: s.G,
- ID: uint64(spanID),
+ ID: uint64(regionID),
Scope: scopeID,
Cname: colorDeepMagenta,
}
@@ -885,12 +885,12 @@ func (ctx *traceContext) emitSpan(s spanDesc) {
ctx.emit(sl0)
sl1 := &ViewerEvent{
- Category: "Span",
+ Category: "Region",
Name: s.Name,
Phase: "e",
Time: float64(s.lastTimestamp()) / 1e3,
Tid: s.G,
- ID: uint64(spanID),
+ ID: uint64(regionID),
Scope: scopeID,
Cname: colorDeepMagenta,
}