OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/color_scheme.html"> | 8 <link rel="import" href="/tracing/base/color_scheme.html"> |
9 <link rel="import" href="/tracing/base/iteration_helpers.html"> | 9 <link rel="import" href="/tracing/base/iteration_helpers.html"> |
10 <link rel="import" href="/tracing/extras/importer/linux_perf/android_parser.html
"> | 10 <link rel="import" href="/tracing/extras/importer/linux_perf/android_parser.html
"> |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 '^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]' + | 83 '^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]' + |
84 '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + | 84 '\\s+[dX.][Nnp.][Hhs.][0-9a-f.]' + |
85 '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); | 85 '\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$'); |
86 var lineParserWithTGID = function(line) { | 86 var lineParserWithTGID = function(line) { |
87 var groups = lineREWithTGID.exec(line); | 87 var groups = lineREWithTGID.exec(line); |
88 if (!groups) { | 88 if (!groups) { |
89 return groups; | 89 return groups; |
90 } | 90 } |
91 | 91 |
92 var tgid = groups[3]; | 92 var tgid = groups[3]; |
93 if (tgid[0] === '-') | 93 if (tgid[0] === '-') tgid = undefined; |
94 tgid = undefined; | |
95 | 94 |
96 return { | 95 return { |
97 threadName: groups[1], | 96 threadName: groups[1], |
98 pid: groups[2], | 97 pid: groups[2], |
99 tgid: tgid, | 98 tgid: tgid, |
100 cpuNumber: groups[4], | 99 cpuNumber: groups[4], |
101 timestamp: groups[5], | 100 timestamp: groups[5], |
102 eventName: groups[6], | 101 eventName: groups[6], |
103 details: groups[7] | 102 details: groups[7] |
104 }; | 103 }; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 160 |
162 /** | 161 /** |
163 * Deduce the format of trace data. Linux kernels prior to 3.3 used one | 162 * Deduce the format of trace data. Linux kernels prior to 3.3 used one |
164 * format (by default); 3.4 and later used another. Additionally, newer | 163 * format (by default); 3.4 and later used another. Additionally, newer |
165 * kernels can optionally trace the TGID. | 164 * kernels can optionally trace the TGID. |
166 * | 165 * |
167 * @return {function} the function for parsing data when the format is | 166 * @return {function} the function for parsing data when the format is |
168 * recognized; otherwise undefined. | 167 * recognized; otherwise undefined. |
169 */ | 168 */ |
170 function autoDetectLineParser(line) { | 169 function autoDetectLineParser(line) { |
171 if (line[0] === '{') | 170 if (line[0] === '{') return false; |
172 return false; | 171 if (lineREWithTGID.test(line)) { |
173 if (lineREWithTGID.test(line)) | |
174 return lineParserWithTGID; | 172 return lineParserWithTGID; |
175 if (lineREWithIRQInfo.test(line)) | 173 } |
| 174 if (lineREWithIRQInfo.test(line)) { |
176 return lineParserWithIRQInfo; | 175 return lineParserWithIRQInfo; |
177 if (lineREWithLegacyFmt.test(line)) | 176 } |
| 177 if (lineREWithLegacyFmt.test(line)) { |
178 return lineParserWithLegacyFmt; | 178 return lineParserWithLegacyFmt; |
| 179 } |
179 return undefined; | 180 return undefined; |
180 } | 181 } |
181 TestExports.autoDetectLineParser = autoDetectLineParser; | 182 TestExports.autoDetectLineParser = autoDetectLineParser; |
182 | 183 |
183 /** | 184 /** |
184 * Guesses whether the provided events is a Linux perf string. | 185 * Guesses whether the provided events is a Linux perf string. |
185 * Looks for the magic string "# tracer" at the start of the file, | 186 * Looks for the magic string "# tracer" at the start of the file, |
186 * or the typical task-pid-cpu-timestamp-function sequence of a typical | 187 * or the typical task-pid-cpu-timestamp-function sequence of a typical |
187 * trace's body. | 188 * trace's body. |
188 * | 189 * |
189 * @return {boolean} True when events is a linux perf array. | 190 * @return {boolean} True when events is a linux perf array. |
190 */ | 191 */ |
191 FTraceImporter.canImport = function(events) { | 192 FTraceImporter.canImport = function(events) { |
192 if (!(typeof(events) === 'string' || events instanceof String)) | 193 if (!(typeof(events) === 'string' || events instanceof String)) { |
193 return false; | 194 return false; |
| 195 } |
194 | 196 |
195 if (FTraceImporter._extractEventsFromSystraceHTML(events, false).ok) | 197 if (FTraceImporter._extractEventsFromSystraceHTML(events, false).ok) { |
196 return true; | 198 return true; |
| 199 } |
197 | 200 |
198 if (FTraceImporter._extractEventsFromSystraceMultiHTML(events, false).ok) | 201 if (FTraceImporter._extractEventsFromSystraceMultiHTML(events, false).ok) { |
199 return true; | 202 return true; |
| 203 } |
200 | 204 |
201 if (/^# tracer:/.test(events)) | 205 if (/^# tracer:/.test(events)) { |
202 return true; | 206 return true; |
| 207 } |
203 | 208 |
204 var lineBreakIndex = events.indexOf('\n'); | 209 var lineBreakIndex = events.indexOf('\n'); |
205 if (lineBreakIndex > -1) | 210 if (lineBreakIndex > -1) { |
206 events = events.substring(0, lineBreakIndex); | 211 events = events.substring(0, lineBreakIndex); |
| 212 } |
207 | 213 |
208 if (autoDetectLineParser(events)) | 214 if (autoDetectLineParser(events)) { |
209 return true; | 215 return true; |
| 216 } |
210 | 217 |
211 return false; | 218 return false; |
212 }; | 219 }; |
213 | 220 |
214 FTraceImporter._extractEventsFromSystraceHTML = function( | 221 FTraceImporter._extractEventsFromSystraceHTML = function( |
215 incomingEvents, produceResult) { | 222 incomingEvents, produceResult) { |
216 var failure = {ok: false}; | 223 var failure = {ok: false}; |
217 if (produceResult === undefined) | 224 if (produceResult === undefined) { |
218 produceResult = true; | 225 produceResult = true; |
| 226 } |
219 | 227 |
220 if (!/^<!DOCTYPE html>/.test(incomingEvents)) | 228 if (!/^<!DOCTYPE html>/.test(incomingEvents)) { |
221 return failure; | 229 return failure; |
| 230 } |
222 var r = new tr.importer.SimpleLineReader(incomingEvents); | 231 var r = new tr.importer.SimpleLineReader(incomingEvents); |
223 | 232 |
224 // Try to find the data... | 233 // Try to find the data... |
225 if (!r.advanceToLineMatching(/^ <script>$/)) | 234 if (!r.advanceToLineMatching(/^ <script>$/)) { |
226 return failure; | 235 return failure; |
227 if (!r.advanceToLineMatching(/^ var linuxPerfData = "\\$/)) | 236 } |
| 237 if (!r.advanceToLineMatching(/^ var linuxPerfData = "\\$/)) { |
228 return failure; | 238 return failure; |
| 239 } |
229 | 240 |
230 var eventsBeginAtLine = r.curLineNumber + 1; | 241 var eventsBeginAtLine = r.curLineNumber + 1; |
231 r.beginSavingLines(); | 242 r.beginSavingLines(); |
232 if (!r.advanceToLineMatching(/^ <\/script>$/)) | 243 if (!r.advanceToLineMatching(/^ <\/script>$/)) { |
233 return failure; | 244 return failure; |
| 245 } |
234 | 246 |
235 var rawEvents = r.endSavingLinesAndGetResult(); | 247 var rawEvents = r.endSavingLinesAndGetResult(); |
236 | 248 |
237 // Drop off first and last event as it contains the tag. | 249 // Drop off first and last event as it contains the tag. |
238 rawEvents = rawEvents.slice(1, rawEvents.length - 1); | 250 rawEvents = rawEvents.slice(1, rawEvents.length - 1); |
239 | 251 |
240 if (!r.advanceToLineMatching(/^<\/body>$/)) | 252 if (!r.advanceToLineMatching(/^<\/body>$/)) { |
241 return failure; | 253 return failure; |
242 if (!r.advanceToLineMatching(/^<\/html>$/)) | 254 } |
| 255 if (!r.advanceToLineMatching(/^<\/html>$/)) { |
243 return failure; | 256 return failure; |
| 257 } |
244 | 258 |
245 function endsWith(str, suffix) { | 259 function endsWith(str, suffix) { |
246 return str.indexOf(suffix, str.length - suffix.length) !== -1; | 260 return str.indexOf(suffix, str.length - suffix.length) !== -1; |
247 } | 261 } |
248 function stripSuffix(str, suffix) { | 262 function stripSuffix(str, suffix) { |
249 if (!endsWith(str, suffix)) | 263 if (!endsWith(str, suffix)) { |
250 return str; | 264 return str; |
| 265 } |
251 return str.substring(str, str.length - suffix.length); | 266 return str.substring(str, str.length - suffix.length); |
252 } | 267 } |
253 | 268 |
254 // Strip off escaping in the file needed to preserve linebreaks. | 269 // Strip off escaping in the file needed to preserve linebreaks. |
255 var events = []; | 270 var events = []; |
256 if (produceResult) { | 271 if (produceResult) { |
257 for (var i = 0; i < rawEvents.length; i++) { | 272 for (var i = 0; i < rawEvents.length; i++) { |
258 var event = rawEvents[i]; | 273 var event = rawEvents[i]; |
259 event = stripSuffix(event, '\\n\\'); | 274 event = stripSuffix(event, '\\n\\'); |
260 events.push(event); | 275 events.push(event); |
261 } | 276 } |
262 } else { | 277 } else { |
263 events = [rawEvents[rawEvents.length - 1]]; | 278 events = [rawEvents[rawEvents.length - 1]]; |
264 } | 279 } |
265 | 280 |
266 // Last event ends differently. Strip that off too, | 281 // Last event ends differently. Strip that off too, |
267 // treating absence of that trailing string as a failure. | 282 // treating absence of that trailing string as a failure. |
268 var oldLastEvent = events[events.length - 1]; | 283 var oldLastEvent = events[events.length - 1]; |
269 var newLastEvent = stripSuffix(oldLastEvent, '\\n";'); | 284 var newLastEvent = stripSuffix(oldLastEvent, '\\n";'); |
270 if (newLastEvent === oldLastEvent) | 285 if (newLastEvent === oldLastEvent) { |
271 return failure; | 286 return failure; |
| 287 } |
272 events[events.length - 1] = newLastEvent; | 288 events[events.length - 1] = newLastEvent; |
273 | 289 |
274 return {ok: true, | 290 return {ok: true, |
275 lines: produceResult ? events : undefined, | 291 lines: produceResult ? events : undefined, |
276 eventsBeginAtLine: eventsBeginAtLine}; | 292 eventsBeginAtLine: eventsBeginAtLine}; |
277 }; | 293 }; |
278 | 294 |
279 FTraceImporter._extractEventsFromSystraceMultiHTML = function( | 295 FTraceImporter._extractEventsFromSystraceMultiHTML = function( |
280 incomingEvents, produceResult) { | 296 incomingEvents, produceResult) { |
281 var failure = {ok: false}; | 297 var failure = {ok: false}; |
282 if (produceResult === undefined) | 298 if (produceResult === undefined) { |
283 produceResult = true; | 299 produceResult = true; |
| 300 } |
284 | 301 |
285 if (!(new RegExp('^<!DOCTYPE HTML>', 'i').test(incomingEvents))) | 302 if (!(new RegExp('^<!DOCTYPE HTML>', 'i').test(incomingEvents))) { |
286 return failure; | 303 return failure; |
| 304 } |
287 | 305 |
288 var r = new tr.importer.SimpleLineReader(incomingEvents); | 306 var r = new tr.importer.SimpleLineReader(incomingEvents); |
289 | 307 |
290 // Try to find the Linux perf trace in any of the trace-data tags | 308 // Try to find the Linux perf trace in any of the trace-data tags |
291 var events = []; | 309 var events = []; |
292 while (!/^# tracer:/.test(events)) { | 310 while (!/^# tracer:/.test(events)) { |
293 if (!r.advanceToLineMatching( | 311 if (!r.advanceToLineMatching( |
294 /^ <script class="trace-data" type="application\/text">$/)) | 312 /^ <script class="trace-data" type="application\/text">$/)) { |
295 return failure; | 313 return failure; |
| 314 } |
296 | 315 |
297 var eventsBeginAtLine = r.curLineNumber + 1; | 316 var eventsBeginAtLine = r.curLineNumber + 1; |
298 | 317 |
299 r.beginSavingLines(); | 318 r.beginSavingLines(); |
300 if (!r.advanceToLineMatching(/^ <\/script>$/)) | 319 if (!r.advanceToLineMatching(/^ <\/script>$/)) return failure; |
301 return failure; | |
302 | 320 |
303 events = r.endSavingLinesAndGetResult(); | 321 events = r.endSavingLinesAndGetResult(); |
304 | 322 |
305 // Drop off first and last event as it contains the tag. | 323 // Drop off first and last event as it contains the tag. |
306 events = events.slice(1, events.length - 1); | 324 events = events.slice(1, events.length - 1); |
307 } | 325 } |
308 | 326 |
309 if (!r.advanceToLineMatching(/^<\/body>$/)) | 327 if (!r.advanceToLineMatching(/^<\/body>$/)) { |
310 return failure; | 328 return failure; |
311 if (!r.advanceToLineMatching(/^<\/html>$/)) | 329 } |
| 330 if (!r.advanceToLineMatching(/^<\/html>$/)) { |
312 return failure; | 331 return failure; |
| 332 } |
313 | 333 |
314 return {ok: true, | 334 return {ok: true, |
315 lines: produceResult ? events : undefined, | 335 lines: produceResult ? events : undefined, |
316 eventsBeginAtLine: eventsBeginAtLine}; | 336 eventsBeginAtLine: eventsBeginAtLine}; |
317 }; | 337 }; |
318 | 338 |
319 FTraceImporter.prototype = { | 339 FTraceImporter.prototype = { |
320 __proto__: tr.importer.Importer.prototype, | 340 __proto__: tr.importer.Importer.prototype, |
321 | 341 |
322 get importerName() { | 342 get importerName() { |
323 return 'FTraceImporter'; | 343 return 'FTraceImporter'; |
324 }, | 344 }, |
325 | 345 |
326 get model() { | 346 get model() { |
327 return this.model_; | 347 return this.model_; |
328 }, | 348 }, |
329 | 349 |
330 /** | 350 /** |
331 * Imports clock sync markers into model_. | 351 * Imports clock sync markers into model_. |
332 */ | 352 */ |
333 importClockSyncMarkers: function() { | 353 importClockSyncMarkers: function() { |
334 this.lazyInit_(); | 354 this.lazyInit_(); |
335 | 355 |
336 this.forEachLine_(function(text, eventBase, cpuNumber, pid, ts) { | 356 this.forEachLine_(function(text, eventBase, cpuNumber, pid, ts) { |
337 var eventName = eventBase.eventName; | 357 var eventName = eventBase.eventName; |
338 if (eventName !== 'tracing_mark_write' && eventName !== '0') | 358 if (eventName !== 'tracing_mark_write' && eventName !== '0') { |
339 return; | 359 return; |
| 360 } |
340 | 361 |
341 if (traceEventClockSyncRE.exec(eventBase.details) || | 362 if (traceEventClockSyncRE.exec(eventBase.details) || |
342 genericClockSyncRE.exec(eventBase.details)) { | 363 genericClockSyncRE.exec(eventBase.details)) { |
343 this.traceClockSyncEvent_(eventName, cpuNumber, pid, ts, eventBase); | 364 this.traceClockSyncEvent_(eventName, cpuNumber, pid, ts, eventBase); |
344 } else if (realTimeClockSyncRE.exec(eventBase.details)) { | 365 } else if (realTimeClockSyncRE.exec(eventBase.details)) { |
345 // TODO(charliea): Migrate this sync to ClockSyncManager. | 366 // TODO(charliea): Migrate this sync to ClockSyncManager. |
346 // This entry syncs CLOCK_REALTIME with CLOCK_MONOTONIC. Store the | 367 // This entry syncs CLOCK_REALTIME with CLOCK_MONOTONIC. Store the |
347 // offset between the two in the model so that importers parsing files | 368 // offset between the two in the model so that importers parsing files |
348 // with CLOCK_REALTIME timestamps can map back to CLOCK_MONOTONIC. | 369 // with CLOCK_REALTIME timestamps can map back to CLOCK_MONOTONIC. |
349 var match = realTimeClockSyncRE.exec(eventBase.details); | 370 var match = realTimeClockSyncRE.exec(eventBase.details); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; | 505 var SCHEDULING_STATE = tr.model.SCHEDULING_STATE; |
485 | 506 |
486 // Push the cpu slices to the threads that they run on. | 507 // Push the cpu slices to the threads that they run on. |
487 for (var cpuNumber in this.model_.kernel.cpus) { | 508 for (var cpuNumber in this.model_.kernel.cpus) { |
488 var cpu = this.model_.kernel.cpus[cpuNumber]; | 509 var cpu = this.model_.kernel.cpus[cpuNumber]; |
489 | 510 |
490 for (var i = 0; i < cpu.slices.length; i++) { | 511 for (var i = 0; i < cpu.slices.length; i++) { |
491 var cpuSlice = cpu.slices[i]; | 512 var cpuSlice = cpu.slices[i]; |
492 | 513 |
493 var thread = this.threadsByLinuxPid[cpuSlice.args.tid]; | 514 var thread = this.threadsByLinuxPid[cpuSlice.args.tid]; |
494 if (!thread) | 515 if (!thread) continue; |
495 continue; | |
496 | 516 |
497 cpuSlice.threadThatWasRunning = thread; | 517 cpuSlice.threadThatWasRunning = thread; |
498 | 518 |
499 if (!thread.tempCpuSlices) | 519 if (!thread.tempCpuSlices) { |
500 thread.tempCpuSlices = []; | 520 thread.tempCpuSlices = []; |
| 521 } |
501 thread.tempCpuSlices.push(cpuSlice); | 522 thread.tempCpuSlices.push(cpuSlice); |
502 } | 523 } |
503 } | 524 } |
504 | 525 |
505 for (var i in this.wakeups_) { | 526 for (var i in this.wakeups_) { |
506 var wakeup = this.wakeups_[i]; | 527 var wakeup = this.wakeups_[i]; |
507 var thread = this.threadsByLinuxPid[wakeup.tid]; | 528 var thread = this.threadsByLinuxPid[wakeup.tid]; |
508 if (!thread) | 529 if (!thread) continue; |
509 continue; | |
510 thread.tempWakeups = thread.tempWakeups || []; | 530 thread.tempWakeups = thread.tempWakeups || []; |
511 thread.tempWakeups.push(wakeup); | 531 thread.tempWakeups.push(wakeup); |
512 } | 532 } |
513 for (var i in this.blockedReasons_) { | 533 for (var i in this.blockedReasons_) { |
514 var reason = this.blockedReasons_[i]; | 534 var reason = this.blockedReasons_[i]; |
515 var thread = this.threadsByLinuxPid[reason.tid]; | 535 var thread = this.threadsByLinuxPid[reason.tid]; |
516 if (!thread) | 536 if (!thread) continue; |
517 continue; | |
518 thread.tempBlockedReasons = thread.tempBlockedReasons || []; | 537 thread.tempBlockedReasons = thread.tempBlockedReasons || []; |
519 thread.tempBlockedReasons.push(reason); | 538 thread.tempBlockedReasons.push(reason); |
520 } | 539 } |
521 | 540 |
522 // Create slices for when the thread is not running. | 541 // Create slices for when the thread is not running. |
523 this.model_.getAllThreads().forEach(function(thread) { | 542 this.model_.getAllThreads().forEach(function(thread) { |
524 if (thread.tempCpuSlices === undefined) | 543 if (thread.tempCpuSlices === undefined) return; |
525 return; | |
526 var origSlices = thread.tempCpuSlices; | 544 var origSlices = thread.tempCpuSlices; |
527 delete thread.tempCpuSlices; | 545 delete thread.tempCpuSlices; |
528 | 546 |
529 origSlices.sort(function(x, y) { | 547 origSlices.sort(function(x, y) { |
530 return x.start - y.start; | 548 return x.start - y.start; |
531 }); | 549 }); |
532 | 550 |
533 var wakeups = thread.tempWakeups || []; | 551 var wakeups = thread.tempWakeups || []; |
534 delete thread.tempWakeups; | 552 delete thread.tempWakeups; |
535 wakeups.sort(function(x, y) { | 553 wakeups.sort(function(x, y) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 if (event) { | 750 if (event) { |
733 // TODO(alexandermont): This section of code seems to be broken. It | 751 // TODO(alexandermont): This section of code seems to be broken. It |
734 // creates an "args" variable, but doesn't seem to do anything with it. | 752 // creates an "args" variable, but doesn't seem to do anything with it. |
735 var name = event[1]; | 753 var name = event[1]; |
736 var pieces = event[2].split(' '); | 754 var pieces = event[2].split(' '); |
737 var args = { | 755 var args = { |
738 perfTs: ts | 756 perfTs: ts |
739 }; | 757 }; |
740 for (var i = 0; i < pieces.length; i++) { | 758 for (var i = 0; i < pieces.length; i++) { |
741 var parts = pieces[i].split('='); | 759 var parts = pieces[i].split('='); |
742 if (parts.length !== 2) | 760 if (parts.length !== 2) { |
743 throw new Error('omgbbq'); | 761 throw new Error('omgbbq'); |
| 762 } |
744 args[parts[0]] = parts[1]; | 763 args[parts[0]] = parts[1]; |
745 } | 764 } |
746 | 765 |
747 this.model_.clockSyncManager.addClockSyncMarker( | 766 this.model_.clockSyncManager.addClockSyncMarker( |
748 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, name, ts); | 767 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, name, ts); |
749 return true; | 768 return true; |
750 } | 769 } |
751 | 770 |
752 // Check to see if we have a "new style" clock sync marker that contains | 771 // Check to see if we have a "new style" clock sync marker that contains |
753 // only a sync ID. | 772 // only a sync ID. |
754 var event = /name=([\w\-]+)/.exec(eventBase.details); | 773 var event = /name=([\w\-]+)/.exec(eventBase.details); |
755 if (event) { | 774 if (event) { |
756 this.model_.clockSyncManager.addClockSyncMarker( | 775 this.model_.clockSyncManager.addClockSyncMarker( |
757 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, event[1], ts); | 776 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, event[1], ts); |
758 return true; | 777 return true; |
759 } | 778 } |
760 | 779 |
761 // Check to see if we have a special clock sync marker that contains both | 780 // Check to see if we have a special clock sync marker that contains both |
762 // the current "ftrace global" time and the current CLOCK_MONOTONIC time. | 781 // the current "ftrace global" time and the current CLOCK_MONOTONIC time. |
763 event = /parent_ts=(\d+\.?\d*)/.exec(eventBase.details); | 782 event = /parent_ts=(\d+\.?\d*)/.exec(eventBase.details); |
764 if (!event) | 783 if (!event) return false; |
765 return false; | |
766 | 784 |
767 var monotonicTs = event[1] * 1000; | 785 var monotonicTs = event[1] * 1000; |
768 // A monotonic timestamp of zero is used as a sentinel value to indicate | 786 // A monotonic timestamp of zero is used as a sentinel value to indicate |
769 // that CLOCK_MONOTONIC and the ftrace global clock are identical. | 787 // that CLOCK_MONOTONIC and the ftrace global clock are identical. |
770 if (monotonicTs === 0) | 788 if (monotonicTs === 0) monotonicTs = ts; |
771 monotonicTs = ts; | |
772 | 789 |
773 if (this.haveClockSyncedMonotonicToGlobal_) | 790 if (this.haveClockSyncedMonotonicToGlobal_) { |
774 // ftrace sometimes includes multiple clock syncs between the monotonic | 791 // ftrace sometimes includes multiple clock syncs between the monotonic |
775 // and global clocks within a single trace. We protect against this by | 792 // and global clocks within a single trace. We protect against this by |
776 // only taking the first one into account. | 793 // only taking the first one into account. |
777 return true; | 794 return true; |
| 795 } |
778 | 796 |
779 // We have a clock sync event that contains two timestamps: a timestamp | 797 // We have a clock sync event that contains two timestamps: a timestamp |
780 // according to the ftrace 'global' clock, and that same timestamp | 798 // according to the ftrace 'global' clock, and that same timestamp |
781 // according to clock_gettime(CLOCK_MONOTONIC). | 799 // according to clock_gettime(CLOCK_MONOTONIC). |
782 this.model_.clockSyncManager.addClockSyncMarker( | 800 this.model_.clockSyncManager.addClockSyncMarker( |
783 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, | 801 tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL, |
784 MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, ts); | 802 MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, ts); |
785 this.model_.clockSyncManager.addClockSyncMarker( | 803 this.model_.clockSyncManager.addClockSyncMarker( |
786 tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC, | 804 tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC, |
787 MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, monotonicTs); | 805 MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID, monotonicTs); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 }.bind(this)); | 868 }.bind(this)); |
851 }, | 869 }, |
852 | 870 |
853 /** | 871 /** |
854 * Walks the this.events_ structure and populates this.lines_. | 872 * Walks the this.events_ structure and populates this.lines_. |
855 */ | 873 */ |
856 parseLines_: function() { | 874 parseLines_: function() { |
857 var lines = []; | 875 var lines = []; |
858 var extractResult = FTraceImporter._extractEventsFromSystraceHTML( | 876 var extractResult = FTraceImporter._extractEventsFromSystraceHTML( |
859 this.events_, true); | 877 this.events_, true); |
860 if (!extractResult.ok) | 878 if (!extractResult.ok) { |
861 extractResult = FTraceImporter._extractEventsFromSystraceMultiHTML( | 879 extractResult = FTraceImporter._extractEventsFromSystraceMultiHTML( |
862 this.events_, true); | 880 this.events_, true); |
| 881 } |
863 var lines = extractResult.ok ? | 882 var lines = extractResult.ok ? |
864 extractResult.lines : this.events_.split('\n'); | 883 extractResult.lines : this.events_.split('\n'); |
865 | 884 |
866 var lineParser = undefined; | 885 var lineParser = undefined; |
867 for (var lineNumber = 0; lineNumber < lines.length; ++lineNumber) { | 886 for (var lineNumber = 0; lineNumber < lines.length; ++lineNumber) { |
868 var line = lines[lineNumber].trim(); | 887 var line = lines[lineNumber].trim(); |
869 if (line.length === 0 || /^#/.test(line)) | 888 if (line.length === 0 || /^#/.test(line)) continue; |
870 continue; | |
871 | 889 |
872 if (!lineParser) { | 890 if (!lineParser) { |
873 lineParser = autoDetectLineParser(line); | 891 lineParser = autoDetectLineParser(line); |
874 if (!lineParser) { | 892 if (!lineParser) { |
875 this.model_.importWarning({ | 893 this.model_.importWarning({ |
876 type: 'parse_error', | 894 type: 'parse_error', |
877 message: 'Cannot parse line: ' + line | 895 message: 'Cannot parse line: ' + line |
878 }); | 896 }); |
879 continue; | 897 continue; |
880 } | 898 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 }; | 940 }; |
923 | 941 |
924 tr.importer.Importer.register(FTraceImporter); | 942 tr.importer.Importer.register(FTraceImporter); |
925 | 943 |
926 return { | 944 return { |
927 FTraceImporter, | 945 FTraceImporter, |
928 _FTraceImporterTestExports: TestExports | 946 _FTraceImporterTestExports: TestExports |
929 }; | 947 }; |
930 }); | 948 }); |
931 </script> | 949 </script> |
OLD | NEW |