1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 'use strict'; 6 7 /** 8 * @fileoverview Parses sync events in the Linux event trace format. 9 */ 10 base.require('tracing.importer.linux_perf.parser'); 11 base.exportTo('tracing.importer.linux_perf', function() { 12 13 var Parser = tracing.importer.linux_perf.Parser; 14 15 /** 16 * Parses linux sync trace events. 17 * @constructor 18 */ 19 function SyncParser(importer) { 20 Parser.call(this, importer); 21 22 importer.registerEventHandler( 23 'sync_timeline', 24 SyncParser.prototype.timelineEvent.bind(this)); 25 importer.registerEventHandler( 26 'sync_wait', 27 SyncParser.prototype.syncWaitEvent.bind(this)); 28 importer.registerEventHandler( 29 'sync_pt', 30 SyncParser.prototype.syncPtEvent.bind(this)); 31 this.model_ = importer.model_; 32 } 33 34 var syncTimelineRE = /name=(\S+) value=(\S*)/; 35 var syncWaitRE = /(\S+) name=(\S+) state=(\d+)/; 36 var syncPtRE = /name=(\S+) value=(\S*)/; 37 38 SyncParser.prototype = { 39 __proto__: Parser.prototype, 40 41 /** 42 * Parses sync events and sets up state in the importer. 43 */ 44 timelineEvent: function(eventName, cpuNumber, pid, 45 ts, eventBase) { 46 var event = syncTimelineRE.exec(eventBase.details); 47 if (!event) 48 return false; 49 50 var thread = this.importer.getOrCreatePseudoThread(event[1]); 51 52 if (thread.lastActiveTs !== undefined) { 53 var duration = ts - thread.lastActiveTs; 54 var value = thread.lastActiveValue; 55 if (value == undefined) 56 value = ' '; 57 var slice = new tracing.trace_model.Slice( 58 '', value, 59 tracing.getStringColorId(value), 60 thread.lastActiveTs, {}, 61 duration); 62 thread.thread.sliceGroup.pushSlice(slice); 63 } 64 thread.lastActiveTs = ts; 65 thread.lastActiveValue = event[2]; 66 return true; 67 }, 68 69 syncWaitEvent: function(eventName, cpuNumber, pid, ts, 70 eventBase) { 71 var event = syncWaitRE.exec(eventBase.details); 72 if (!event) 73 return false; 74 75 if (eventBase.tgid === undefined) { 76 return false; 77 } 78 79 var tgid = parseInt(eventBase.tgid); 80 var thread = this.model_.getOrCreateProcess(tgid) 81 .getOrCreateThread(pid); 82 thread.name = eventBase.threadName; 83 var slices = thread.kernelSliceGroup; 84 if (!slices.isTimestampValidForBeginOrEnd(ts)) { 85 this.model_.importErrors.push('Timestamps are moving backward.'); 86 return false; 87 } 88 89 var name = 'fence_wait("' + event[2] + '")'; 90 if (event[1] == 'begin') { 91 var slice = slices.beginSlice(null, name, ts, { 92 'Start state': event[3] 93 }); 94 } else if (event[1] == 'end') { 95 if (slices.openSliceCount > 0) { 96 slices.endSlice(ts); 97 } 98 } else { 99 return false; 100 } 101 102 return true; 103 }, 104 105 syncPtEvent: function(eventName, cpuNumber, pid, ts, eventBase) { 106 var event = syncPtRE.exec(eventBase.details); 107 if (!event) 108 return false; 109 110 return true; 111 112 var thread = this.importer.getOrCreateKernelThread( 113 eventBase[1]).thread; 114 thread.syncWaitSyncPts[event[1]] = event[2]; 115 return true; 116 } 117 }; 118 119 Parser.registerSubtype(SyncParser); 120 121 return { 122 SyncParser: SyncParser 123 }; 124 }); 125