compiler: don't insert write barriers if we've seen errors
[official-gcc.git] / libgo / go / internal / trace / goroutines.go
blob923a157416f1f452fef8bcbcdcd55c0d25e7ca2b
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.
5 package trace
7 // GDesc contains statistics about execution of a single goroutine.
8 type GDesc struct {
9 ID uint64
10 Name string
11 PC uint64
12 CreationTime int64
13 StartTime int64
14 EndTime int64
16 ExecTime int64
17 SchedWaitTime int64
18 IOTime int64
19 BlockTime int64
20 SyscallTime int64
21 GCTime int64
22 SweepTime int64
23 TotalTime int64
25 *gdesc // private part
28 // gdesc is a private part of GDesc that is required only during analysis.
29 type gdesc struct {
30 lastStartTime int64
31 blockNetTime int64
32 blockSyncTime int64
33 blockSyscallTime int64
34 blockSweepTime int64
35 blockGCTime int64
36 blockSchedTime 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)
42 var lastTs int64
43 var gcStartTime int64
44 for _, ev := range events {
45 lastTs = ev.Ts
46 switch ev.Type {
47 case EvGoCreate:
48 g := &GDesc{ID: ev.Args[0], CreationTime: ev.Ts, gdesc: new(gdesc)}
49 g.blockSchedTime = ev.Ts
50 gs[g.ID] = g
51 case EvGoStart, EvGoStartLabel:
52 g := gs[ev.G]
53 if g.PC == 0 {
54 g.PC = ev.Stk[0].PC
55 g.Name = ev.Stk[0].Fn
57 g.lastStartTime = ev.Ts
58 if g.StartTime == 0 {
59 g.StartTime = ev.Ts
61 if g.blockSchedTime != 0 {
62 g.SchedWaitTime += ev.Ts - g.blockSchedTime
63 g.blockSchedTime = 0
65 case EvGoEnd, EvGoStop:
66 g := gs[ev.G]
67 g.ExecTime += ev.Ts - g.lastStartTime
68 g.TotalTime = ev.Ts - g.CreationTime
69 g.EndTime = ev.Ts
70 case EvGoBlockSend, EvGoBlockRecv, EvGoBlockSelect,
71 EvGoBlockSync, EvGoBlockCond:
72 g := gs[ev.G]
73 g.ExecTime += ev.Ts - g.lastStartTime
74 g.blockSyncTime = ev.Ts
75 case EvGoSched, EvGoPreempt:
76 g := gs[ev.G]
77 g.ExecTime += ev.Ts - g.lastStartTime
78 g.blockSchedTime = ev.Ts
79 case EvGoSleep, EvGoBlock:
80 g := gs[ev.G]
81 g.ExecTime += ev.Ts - g.lastStartTime
82 case EvGoBlockNet:
83 g := gs[ev.G]
84 g.ExecTime += ev.Ts - g.lastStartTime
85 g.blockNetTime = ev.Ts
86 case EvGoBlockGC:
87 g := gs[ev.G]
88 g.ExecTime += ev.Ts - g.lastStartTime
89 g.blockGCTime = ev.Ts
90 case EvGoUnblock:
91 g := gs[ev.Args[0]]
92 if g.blockNetTime != 0 {
93 g.IOTime += ev.Ts - g.blockNetTime
94 g.blockNetTime = 0
96 if g.blockSyncTime != 0 {
97 g.BlockTime += ev.Ts - g.blockSyncTime
98 g.blockSyncTime = 0
100 g.blockSchedTime = ev.Ts
101 case EvGoSysBlock:
102 g := gs[ev.G]
103 g.ExecTime += ev.Ts - g.lastStartTime
104 g.blockSyscallTime = ev.Ts
105 case EvGoSysExit:
106 g := gs[ev.G]
107 if g.blockSyscallTime != 0 {
108 g.SyscallTime += ev.Ts - g.blockSyscallTime
109 g.blockSyscallTime = 0
111 g.blockSchedTime = ev.Ts
112 case EvGCSweepStart:
113 g := gs[ev.G]
114 if g != nil {
115 // Sweep can happen during GC on system goroutine.
116 g.blockSweepTime = ev.Ts
118 case EvGCSweepDone:
119 g := gs[ev.G]
120 if g != nil && g.blockSweepTime != 0 {
121 g.SweepTime += ev.Ts - g.blockSweepTime
122 g.blockSweepTime = 0
124 case EvGCStart:
125 gcStartTime = ev.Ts
126 case EvGCDone:
127 for _, g := range gs {
128 if g.EndTime == 0 {
129 g.GCTime += ev.Ts - gcStartTime
135 for _, g := range gs {
136 if g.TotalTime == 0 {
137 g.TotalTime = lastTs - g.CreationTime
139 if g.EndTime == 0 {
140 g.EndTime = lastTs
142 if g.blockNetTime != 0 {
143 g.IOTime += lastTs - g.blockNetTime
144 g.blockNetTime = 0
146 if g.blockSyncTime != 0 {
147 g.BlockTime += lastTs - g.blockSyncTime
148 g.blockSyncTime = 0
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
156 g.blockSchedTime = 0
158 g.gdesc = nil
161 return gs
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)
169 gmap[goid] = true
170 for i := 0; i < 2; i++ {
171 gmap1 := make(map[uint64]bool)
172 for g := range gmap {
173 gmap1[g] = true
175 for _, ev := range events {
176 if ev.Type == EvGoUnblock && gmap[ev.Args[0]] {
177 gmap1[ev.G] = true
180 gmap = gmap1
182 gmap[0] = true // for GC events
183 return gmap