1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // GDesc contains statistics about execution of a single goroutine.
25 *gdesc
// private part
28 // gdesc is a private part of GDesc that is required only during analysis.
33 blockSyscallTime
int64
39 // GoroutineStats generates statistics for all goroutines in the trace.
40 func GoroutineStats(events
[]*Event
) map[uint64]*GDesc
{
41 gs
:= make(map[uint64]*GDesc
)
44 for _
, ev
:= range events
{
48 g
:= &GDesc
{ID
: ev
.Args
[0], CreationTime
: ev
.Ts
, gdesc
: new(gdesc
)}
49 g
.blockSchedTime
= ev
.Ts
51 case EvGoStart
, EvGoStartLabel
:
57 g
.lastStartTime
= ev
.Ts
61 if g
.blockSchedTime
!= 0 {
62 g
.SchedWaitTime
+= ev
.Ts
- g
.blockSchedTime
65 case EvGoEnd
, EvGoStop
:
67 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
68 g
.TotalTime
= ev
.Ts
- g
.CreationTime
70 case EvGoBlockSend
, EvGoBlockRecv
, EvGoBlockSelect
,
71 EvGoBlockSync
, EvGoBlockCond
:
73 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
74 g
.blockSyncTime
= ev
.Ts
75 case EvGoSched
, EvGoPreempt
:
77 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
78 g
.blockSchedTime
= ev
.Ts
79 case EvGoSleep
, EvGoBlock
:
81 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
84 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
85 g
.blockNetTime
= ev
.Ts
88 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
92 if g
.blockNetTime
!= 0 {
93 g
.IOTime
+= ev
.Ts
- g
.blockNetTime
96 if g
.blockSyncTime
!= 0 {
97 g
.BlockTime
+= ev
.Ts
- g
.blockSyncTime
100 g
.blockSchedTime
= ev
.Ts
103 g
.ExecTime
+= ev
.Ts
- g
.lastStartTime
104 g
.blockSyscallTime
= ev
.Ts
107 if g
.blockSyscallTime
!= 0 {
108 g
.SyscallTime
+= ev
.Ts
- g
.blockSyscallTime
109 g
.blockSyscallTime
= 0
111 g
.blockSchedTime
= ev
.Ts
115 // Sweep can happen during GC on system goroutine.
116 g
.blockSweepTime
= ev
.Ts
120 if g
!= nil && g
.blockSweepTime
!= 0 {
121 g
.SweepTime
+= ev
.Ts
- g
.blockSweepTime
127 for _
, g
:= range gs
{
129 g
.GCTime
+= ev
.Ts
- gcStartTime
135 for _
, g
:= range gs
{
136 if g
.TotalTime
== 0 {
137 g
.TotalTime
= lastTs
- g
.CreationTime
142 if g
.blockNetTime
!= 0 {
143 g
.IOTime
+= lastTs
- g
.blockNetTime
146 if g
.blockSyncTime
!= 0 {
147 g
.BlockTime
+= lastTs
- g
.blockSyncTime
150 if g
.blockSyscallTime
!= 0 {
151 g
.SyscallTime
+= lastTs
- g
.blockSyscallTime
152 g
.blockSyscallTime
= 0
154 if g
.blockSchedTime
!= 0 {
155 g
.SchedWaitTime
+= lastTs
- g
.blockSchedTime
164 // RelatedGoroutines finds a set of goroutines related to goroutine goid.
165 func RelatedGoroutines(events
[]*Event
, goid
uint64) map[uint64]bool {
166 // BFS of depth 2 over "unblock" edges
167 // (what goroutines unblock goroutine goid?).
168 gmap
:= make(map[uint64]bool)
170 for i
:= 0; i
< 2; i
++ {
171 gmap1
:= make(map[uint64]bool)
172 for g
:= range gmap
{
175 for _
, ev
:= range events
{
176 if ev
.Type
== EvGoUnblock
&& gmap
[ev
.Args
[0]] {
182 gmap
[0] = true // for GC events