8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use std:: time:: { Instant } ;
11
12
use rustc:: util:: common:: { ProfQDumpParams , ProfileQueriesMsg , profq_msg, profq_set_chan} ;
12
13
use std:: sync:: mpsc:: { Receiver } ;
13
14
use std:: io:: { Write } ;
@@ -41,14 +42,30 @@ pub fn dump(path:String) {
41
42
let _ = rx. recv ( ) . unwrap ( ) ;
42
43
}
43
44
45
+ // State for parsing recursive trace structure in separate thread, via messages
46
+ #[ derive( Clone , Eq , PartialEq ) ]
47
+ enum ParseState {
48
+ // No (local) parse state; may be parsing a tree, focused on a
49
+ // sub-tree that could be anything.
50
+ Clear ,
51
+ // Have Query information from the last message
52
+ HaveQuery ( trace:: Query , Instant ) ,
53
+ // Have "time-begin" information from the last message (doit flag, and message)
54
+ HaveTimeBegin ( String , Instant ) ,
55
+ }
56
+ struct StackFrame {
57
+ pub parse_st : ParseState ,
58
+ pub traces : Vec < trace:: Rec > ,
59
+ }
60
+
44
61
// profiling thread; retains state (in local variables) and dump traces, upon request.
45
62
fn profile_queries_thread ( r : Receiver < ProfileQueriesMsg > ) {
46
63
use self :: trace:: * ;
47
64
use std:: fs:: File ;
48
65
use std:: time:: { Instant } ;
49
66
50
67
let mut profq_msgs : Vec < ProfileQueriesMsg > = vec ! [ ] ;
51
- let mut frame : StackFrame = StackFrame { parse_st : ParseState :: NoQuery , traces : vec ! [ ] } ;
68
+ let mut frame : StackFrame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
52
69
let mut stack : Vec < StackFrame > = vec ! [ ] ;
53
70
loop {
54
71
let msg = r. recv ( ) ;
@@ -64,7 +81,7 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
64
81
ProfileQueriesMsg :: Halt => return ,
65
82
ProfileQueriesMsg :: Dump ( params) => {
66
83
assert ! ( stack. len( ) == 0 ) ;
67
- assert ! ( frame. parse_st == trace :: ParseState :: NoQuery ) ;
84
+ assert ! ( frame. parse_st == ParseState :: Clear ) ;
68
85
{
69
86
// write log of all messages
70
87
if params. dump_profq_msg_log {
@@ -94,6 +111,10 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
94
111
trace:: write_traces ( & mut html_file, & mut counts_file, & frame. traces ) ;
95
112
write ! ( html_file, "</body>\n </html>\n " ) . unwrap ( ) ;
96
113
114
+ let ack_path = format ! ( "{}.ack" , params. path) ;
115
+ let ack_file = File :: create ( & ack_path) . unwrap ( ) ;
116
+ drop ( ack_file) ;
117
+
97
118
// Tell main thread that we are done, e.g., so it can exit
98
119
params. ack . send ( ( ) ) . unwrap ( ) ;
99
120
}
@@ -108,35 +129,33 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
108
129
( _, ProfileQueriesMsg :: Halt ) => unreachable ! ( ) ,
109
130
( _, ProfileQueriesMsg :: Dump ( _) ) => unreachable ! ( ) ,
110
131
111
- // Parse State: NoQuery
112
- ( ParseState :: NoQuery ,
132
+ // Parse State: Clear
133
+ ( ParseState :: Clear ,
113
134
ProfileQueriesMsg :: QueryBegin ( span, querymsg) ) => {
114
135
let start = Instant :: now ( ) ;
115
136
frame. parse_st = ParseState :: HaveQuery
116
137
( Query { span : span, msg : querymsg} , start)
117
138
} ,
118
- ( ParseState :: NoQuery ,
139
+ ( ParseState :: Clear ,
119
140
ProfileQueriesMsg :: CacheHit ) => {
120
141
panic ! ( "parse error: unexpected CacheHit; expected QueryBegin" )
121
142
} ,
122
- ( ParseState :: NoQuery ,
143
+ ( ParseState :: Clear ,
123
144
ProfileQueriesMsg :: ProviderBegin ) => {
124
145
panic ! ( "parse error: expected QueryBegin before beginning a provider" )
125
146
} ,
126
- ( ParseState :: NoQuery ,
147
+ ( ParseState :: Clear ,
127
148
ProfileQueriesMsg :: ProviderEnd ) => {
128
149
let provider_extent = frame. traces ;
129
150
match stack. pop ( ) {
130
151
None =>
131
152
panic ! ( "parse error: expected a stack frame; found an empty stack" ) ,
132
153
Some ( old_frame) => {
133
154
match old_frame. parse_st {
134
- ParseState :: NoQuery =>
135
- panic ! ( "parse error: expected a stack frame for a query" ) ,
136
- ParseState :: HaveQuery ( q, start) => {
155
+ ParseState :: HaveQuery ( q, start) => {
137
156
let duration = start. elapsed ( ) ;
138
157
frame = StackFrame {
139
- parse_st : ParseState :: NoQuery ,
158
+ parse_st : ParseState :: Clear ,
140
159
traces : old_frame. traces
141
160
} ;
142
161
let trace = Rec {
@@ -146,11 +165,66 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
146
165
duration : duration,
147
166
} ;
148
167
frame. traces . push ( trace ) ;
149
- }
168
+ } ,
169
+ _ => panic ! ( "internal parse error: malformed parse stack" )
150
170
}
151
171
}
152
172
}
153
- }
173
+ } ,
174
+
175
+
176
+ ( ParseState :: Clear ,
177
+ ProfileQueriesMsg :: TimeBegin ( msg) ) => {
178
+ let start = Instant :: now ( ) ;
179
+ frame. parse_st = ParseState :: HaveTimeBegin ( msg, start) ;
180
+ stack. push ( frame) ;
181
+ frame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
182
+ } ,
183
+ ( _, ProfileQueriesMsg :: TimeBegin ( _) ) =>
184
+ panic ! ( "parse error; did not expect time begin here" ) ,
185
+
186
+ ( ParseState :: Clear ,
187
+ ProfileQueriesMsg :: TimeEnd ) => {
188
+ let provider_extent = frame. traces ;
189
+ match stack. pop ( ) {
190
+ None =>
191
+ panic ! ( "parse error: expected a stack frame; found an empty stack" ) ,
192
+ Some ( old_frame) => {
193
+ match old_frame. parse_st {
194
+ ParseState :: HaveTimeBegin ( msg, start) => {
195
+ let duration = start. elapsed ( ) ;
196
+ frame = StackFrame {
197
+ parse_st : ParseState :: Clear ,
198
+ traces : old_frame. traces
199
+ } ;
200
+ let trace = Rec {
201
+ effect : Effect :: TimeBegin ( msg) ,
202
+ extent : Box :: new ( provider_extent) ,
203
+ start : start,
204
+ duration : duration,
205
+ } ;
206
+ frame. traces . push ( trace ) ;
207
+ } ,
208
+ _ => panic ! ( "internal parse error: malformed parse stack" )
209
+ }
210
+ }
211
+ }
212
+ } ,
213
+ ( _, ProfileQueriesMsg :: TimeEnd ) => { panic ! ( "parse error" ) }
214
+
215
+
216
+ // Parse State: HaveTimeBegin -- for timing old
217
+ // passes in driver (outside of query model, but
218
+ // still in use)
219
+ ( ParseState :: HaveTimeBegin ( _, _) ,
220
+ ProfileQueriesMsg :: ProviderBegin ) => {
221
+ } ,
222
+ ( ParseState :: HaveTimeBegin ( _, _) ,
223
+ ProfileQueriesMsg :: CacheHit ) => { unreachable ! ( ) } ,
224
+ ( ParseState :: HaveTimeBegin ( _, _) ,
225
+ ProfileQueriesMsg :: QueryBegin ( _, _) ) => { unreachable ! ( ) } ,
226
+ ( ParseState :: HaveTimeBegin ( _, _) ,
227
+ ProfileQueriesMsg :: ProviderEnd ) => { unreachable ! ( ) } ,
154
228
155
229
// Parse State: HaveQuery
156
230
( ParseState :: HaveQuery ( q, start) ,
@@ -163,12 +237,12 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
163
237
duration : duration,
164
238
} ;
165
239
frame. traces . push ( trace ) ;
166
- frame. parse_st = ParseState :: NoQuery ;
240
+ frame. parse_st = ParseState :: Clear ;
167
241
} ,
168
242
( ParseState :: HaveQuery ( _, _) ,
169
243
ProfileQueriesMsg :: ProviderBegin ) => {
170
244
stack. push ( frame) ;
171
- frame = StackFrame { parse_st : ParseState :: NoQuery , traces : vec ! [ ] } ;
245
+ frame = StackFrame { parse_st : ParseState :: Clear , traces : vec ! [ ] } ;
172
246
} ,
173
247
( ParseState :: HaveQuery ( q, _) ,
174
248
ProfileQueriesMsg :: ProviderEnd ) => {
0 commit comments