diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/trace/trace.go | 25 |
1 files changed, 15 insertions, 10 deletions
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)}) |
