OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 /** | 6 /** |
7 * @fileoverview TimelineModel is a parsed representation of the | 7 * @fileoverview TimelineModel is a parsed representation of the |
8 * TraceEvents obtained from base/trace_event in which the begin-end | 8 * TraceEvents obtained from base/trace_event in which the begin-end |
9 * tokens are converted into a hierarchy of processes, threads, | 9 * tokens are converted into a hierarchy of processes, threads, |
10 * subrows, and slices. | 10 * subrows, and slices. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 * @constructor | 58 * @constructor |
59 */ | 59 */ |
60 function TimelineThread(parent, tid) { | 60 function TimelineThread(parent, tid) { |
61 this.parent = parent; | 61 this.parent = parent; |
62 this.tid = tid; | 62 this.tid = tid; |
63 this.subRows = [[]]; | 63 this.subRows = [[]]; |
64 this.nonNestedSubRows = []; | 64 this.nonNestedSubRows = []; |
65 } | 65 } |
66 | 66 |
67 TimelineThread.prototype = { | 67 TimelineThread.prototype = { |
68 name: undefined, | |
James Hawkins
2011/07/28 21:52:15
Document var. If it's intended to be private, appe
nduca
2011/08/01 01:22:45
Done.
| |
69 | |
68 getSubrow: function(i) { | 70 getSubrow: function(i) { |
69 while (i >= this.subRows.length) | 71 while (i >= this.subRows.length) |
70 this.subRows.push([]); | 72 this.subRows.push([]); |
71 return this.subRows[i]; | 73 return this.subRows[i]; |
72 }, | 74 }, |
73 | 75 |
74 addNonNestedSlice: function(slice) { | 76 addNonNestedSlice: function(slice) { |
75 for (var i = 0; i < this.nonNestedSubRows.length; i++) { | 77 for (var i = 0; i < this.nonNestedSubRows.length; i++) { |
76 var currSubRow = this.nonNestedSubRows[i]; | 78 var currSubRow = this.nonNestedSubRows[i]; |
77 var lastSlice = currSubRow[currSubRow.length - 1]; | 79 var lastSlice = currSubRow[currSubRow.length - 1]; |
78 if (slice.start >= lastSlice.start + lastSlice.duration) { | 80 if (slice.start >= lastSlice.start + lastSlice.duration) { |
79 currSubRow.push(slice); | 81 currSubRow.push(slice); |
80 return; | 82 return; |
81 } | 83 } |
82 } | 84 } |
83 this.nonNestedSubRows.push([slice]); | 85 this.nonNestedSubRows.push([slice]); |
84 }, | 86 }, |
85 | 87 |
86 updateBounds: function() { | 88 updateBounds: function() { |
87 var slices = this.subRows[0]; | 89 var values = []; |
88 if (slices.length != 0) { | 90 var slices; |
89 this.minTimestamp = slices[0].start; | 91 if (this.subRows[0].length != 0) { |
90 this.maxTimestamp = slices[slices.length - 1].end; | 92 slices = this.subRows[0]; |
93 values.push(slices[0].start); | |
94 values.push(slices[slices.length - 1].end); | |
95 } | |
96 for (var i = 0; i < this.nonNestedSubRows.length; ++i) { | |
97 slices = this.nonNestedSubRows[i]; | |
98 values.push(slices[0].start); | |
99 values.push(slices[slices.length - 1].end); | |
100 } | |
101 if (values.length) { | |
102 this.minTimestamp = Math.min.apply(Math, values); | |
103 this.maxTimestamp = Math.max.apply(Math, values); | |
91 } else { | 104 } else { |
92 this.minTimestamp = undefined; | 105 this.minTimestamp = undefined; |
93 this.maxTimestamp = undefined; | 106 this.maxTimestamp = undefined; |
94 } | 107 } |
95 } | 108 } |
96 | 109 |
97 }; | 110 }; |
111 /** | |
112 * Comparison between threads that orders first by pid, | |
113 * then by names, then by tid. | |
114 */ | |
115 TimelineThread.compare = function(x,y) { | |
116 if(x.parent.pid == y.parent.pid) { | |
117 if (x.name && y.name) { | |
118 var tmp = x.name.localeCompare(y.name); | |
119 if (tmp == 0) | |
120 return x.tid - y.tid; | |
121 return tmp; | |
122 } else if(x.name) { | |
123 return -1; | |
124 } else if(y.name){ | |
125 return 1; | |
126 } else { | |
127 return x.tid - y.tid; | |
128 } | |
129 } else { | |
130 return x.parent.pid - y.parent.pid; | |
131 } | |
132 }; | |
133 | |
98 | 134 |
99 /** | 135 /** |
100 * The TimelineProcess represents a single process in the | 136 * The TimelineProcess represents a single process in the |
101 * trace. Right now, we keep this around purely for bookkeeping | 137 * trace. Right now, we keep this around purely for bookkeeping |
102 * reasons. | 138 * reasons. |
103 * @constructor | 139 * @constructor |
104 */ | 140 */ |
105 function TimelineProcess(pid) { | 141 function TimelineProcess(pid) { |
106 this.pid = pid; | 142 this.pid = pid; |
107 this.threads = {}; | 143 this.threads = {}; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 | 258 |
223 // Add the slice to the subSlices array of its parent. | 259 // Add the slice to the subSlices array of its parent. |
224 if (state.openSlices.length) { | 260 if (state.openSlices.length) { |
225 var parentSlice = state.openSlices[state.openSlices.length - 1]; | 261 var parentSlice = state.openSlices[state.openSlices.length - 1]; |
226 parentSlice.slice.subSlices.push(slice); | 262 parentSlice.slice.subSlices.push(slice); |
227 } | 263 } |
228 } | 264 } |
229 } else if (event.ph == 'I') { | 265 } else if (event.ph == 'I') { |
230 // TODO(nduca): Implement parsing of immediate events. | 266 // TODO(nduca): Implement parsing of immediate events. |
231 console.log('Parsing of I-type events not implemented.'); | 267 console.log('Parsing of I-type events not implemented.'); |
268 } else if (event.ph == 'M') { | |
269 if (event.name == 'thread_name') { | |
270 var thread = this.getProcess(event.pid).getThread(event.tid); | |
271 thread.name = event.args.name; | |
272 } else { | |
273 console.log('Unrecognized metadata name: ' + event.name); | |
James Hawkins
2011/07/28 21:52:15
Remove console spam here and elsewhere.
nduca
2011/08/01 01:22:45
Done.
| |
274 } | |
232 } else { | 275 } else { |
233 throw new Error('Unrecognized event phase: ' + event.ph + | 276 console.log('Unrecognized event phase: ' + event.ph + |
234 '(' + event.name + ')'); | 277 '(' + event.name + ')'); |
235 } | 278 } |
236 } | 279 } |
237 | 280 this.pruneEmptyThreads(); |
238 this.updateBounds(); | 281 this.updateBounds(); |
239 | 282 |
240 // Add end events for any events that are still on the stack. These | 283 // Add end events for any events that are still on the stack. These |
241 // are events that were still open when trace was ended, and can often | 284 // are events that were still open when trace was ended, and can often |
242 // indicate deadlock behavior. | 285 // indicate deadlock behavior. |
243 for (var ptid in threadStateByPTID) { | 286 for (var ptid in threadStateByPTID) { |
244 var state = threadStateByPTID[ptid]; | 287 var state = threadStateByPTID[ptid]; |
245 while (state.openSlices.length > 0) { | 288 while (state.openSlices.length > 0) { |
246 var slice = state.openSlices.pop(); | 289 var slice = state.openSlices.pop(); |
247 slice.slice.duration = this.maxTimestamp - slice.slice.start; | 290 slice.slice.duration = this.maxTimestamp - slice.slice.start; |
(...skipping 13 matching lines...) Expand all Loading... | |
261 } | 304 } |
262 } | 305 } |
263 | 306 |
264 this.shiftWorldToMicroseconds(); | 307 this.shiftWorldToMicroseconds(); |
265 | 308 |
266 var boost = (this.maxTimestamp - this.minTimestamp) * 0.15; | 309 var boost = (this.maxTimestamp - this.minTimestamp) * 0.15; |
267 this.minTimestamp = this.minTimestamp - boost; | 310 this.minTimestamp = this.minTimestamp - boost; |
268 this.maxTimestamp = this.maxTimestamp + boost; | 311 this.maxTimestamp = this.maxTimestamp + boost; |
269 }, | 312 }, |
270 | 313 |
314 pruneEmptyThreads: function() { | |
James Hawkins
2011/07/28 21:52:15
Document method.
nduca
2011/08/01 01:22:45
Done.
| |
315 for (var pid in this.processes) { | |
316 var process = this.processes[pid]; | |
317 var prunedThreads = []; | |
318 for (var tid in process.threads) { | |
319 var thread = process.threads[tid]; | |
320 if (thread.subRows[0].length) | |
321 prunedThreads.push(thread); | |
322 } | |
323 process.threads = prunedThreads; | |
324 } | |
325 }, | |
326 | |
271 updateBounds: function() { | 327 updateBounds: function() { |
272 var wmin = Infinity; | 328 var wmin = Infinity; |
273 var wmax = -wmin; | 329 var wmax = -wmin; |
274 var threads = this.getAllThreads(); | 330 var threads = this.getAllThreads(); |
275 for (var tI = 0; tI < threads.length; tI++) { | 331 for (var tI = 0; tI < threads.length; tI++) { |
276 var thread = threads[tI]; | 332 var thread = threads[tI]; |
277 thread.updateBounds(); | 333 thread.updateBounds(); |
278 if (thread.minTimestamp && thread.maxTimestamp) { | 334 if (thread.minTimestamp != undefined && |
335 thread.maxTimestamp != undefined) { | |
279 wmin = Math.min(wmin, thread.minTimestamp); | 336 wmin = Math.min(wmin, thread.minTimestamp); |
280 wmax = Math.max(wmax, thread.maxTimestamp); | 337 wmax = Math.max(wmax, thread.maxTimestamp); |
281 } | 338 } |
282 } | 339 } |
283 this.minTimestamp = wmin; | 340 this.minTimestamp = wmin; |
284 this.maxTimestamp = wmax; | 341 this.maxTimestamp = wmax; |
285 }, | 342 }, |
286 | 343 |
287 shiftWorldToMicroseconds: function() { | 344 shiftWorldToMicroseconds: function() { |
288 var timeBase = this.minTimestamp; | 345 var timeBase = this.minTimestamp; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 | 377 |
321 }; | 378 }; |
322 | 379 |
323 return { | 380 return { |
324 TimelineSlice: TimelineSlice, | 381 TimelineSlice: TimelineSlice, |
325 TimelineThread: TimelineThread, | 382 TimelineThread: TimelineThread, |
326 TimelineProcess: TimelineProcess, | 383 TimelineProcess: TimelineProcess, |
327 TimelineModel: TimelineModel | 384 TimelineModel: TimelineModel |
328 }; | 385 }; |
329 }); | 386 }); |
OLD | NEW |