Navigation
@@ -1578,7 +1605,9 @@ x-timeline-view{-webkit-flex-direction:column;cursor:default;display:-webkit-fle
-»
+
+ »
+
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index d469cdede0..eb1aecdefd 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -130,16 +130,17 @@ type frameNode struct {
}
type ViewerData struct {
- Events []*ViewerEvent `json:"traceEvents"`
- Frames map[string]ViewerFrame `json:"stackFrames"`
+ Events []*ViewerEvent `json:"traceEvents"`
+ Frames map[string]ViewerFrame `json:"stackFrames"`
+ TimeUnit string `json:"displayTimeUnit"`
}
type ViewerEvent struct {
Name string `json:"name,omitempty"`
Phase string `json:"ph"`
Scope string `json:"s,omitempty"`
- Time int64 `json:"ts"`
- Dur int64 `json:"dur,omitempty"`
+ Time float64 `json:"ts"`
+ Dur float64 `json:"dur,omitempty"`
Pid uint64 `json:"pid"`
Tid uint64 `json:"tid"`
ID uint64 `json:"id,omitempty"`
@@ -172,6 +173,7 @@ func generateTrace(params *traceParams) ViewerData {
ctx := &traceContext{traceParams: params}
ctx.frameTree.children = make(map[uint64]frameNode)
ctx.data.Frames = make(map[string]ViewerFrame)
+ ctx.data.TimeUnit = "ns"
maxProc := 0
gnames := make(map[uint64]string)
for _, ev := range ctx.events {
@@ -322,12 +324,9 @@ func (ctx *traceContext) emit(e *ViewerEvent) {
ctx.data.Events = append(ctx.data.Events, e)
}
-func (ctx *traceContext) time(ev *trace.Event) int64 {
- // NOTE: trace viewer wants timestamps in microseconds and it does not
- // handle fractional timestamps (rounds them). We give it timestamps
- // in nanoseconds to avoid rounding. See:
- // https://github.com/google/trace-viewer/issues/624
- return ev.Ts - ctx.startTime
+func (ctx *traceContext) time(ev *trace.Event) float64 {
+ // Trace viewer wants timestamps in microseconds.
+ return float64(ev.Ts-ctx.startTime) / 1000
}
func (ctx *traceContext) proc(ev *trace.Event) uint64 {
@@ -408,6 +407,12 @@ func (ctx *traceContext) emitArrow(ev *trace.Event, name string) {
return
}
+ if ev.P == trace.NetpollP || ev.P == trace.TimerP || ev.P == trace.SyscallP {
+ // Trace-viewer discards arrows if they don't start/end inside of a slice or instant.
+ // So emit a fake instant at the start of the arrow.
+ ctx.emitInstant(&trace.Event{P: ev.P, Ts: ev.Ts}, "unblock")
+ }
+
ctx.arrowSeq++
ctx.emit(&ViewerEvent{Name: name, Phase: "s", Tid: ctx.proc(ev), ID: ctx.arrowSeq, Time: ctx.time(ev), Stack: ctx.stack(ev.Stk)})
ctx.emit(&ViewerEvent{Name: name, Phase: "t", Tid: ctx.proc(ev.Link), ID: ctx.arrowSeq, Time: ctx.time(ev.Link)})