3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
8 <link rel="import" href="/tracing/importer/linux_perf/parser.html">
14 * @fileoverview Parses filesystem and block device events in the Linux event
17 tvcm.exportTo('tracing.importer.linux_perf', function() {
19 var Parser = tracing.importer.linux_perf.Parser;
22 * Parses linux filesystem and block device trace events.
25 function DiskParser(importer) {
26 Parser.call(this, importer);
28 importer.registerEventHandler('ext4_sync_file_enter',
29 DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));
30 importer.registerEventHandler('ext4_sync_file_exit',
31 DiskParser.prototype.ext4SyncFileExitEvent.bind(this));
32 importer.registerEventHandler('block_rq_issue',
33 DiskParser.prototype.blockRqIssueEvent.bind(this));
34 importer.registerEventHandler('block_rq_complete',
35 DiskParser.prototype.blockRqCompleteEvent.bind(this));
38 DiskParser.prototype = {
39 __proto__: Parser.prototype,
41 openAsyncSlice: function(ts, category, threadName, pid, key, name) {
42 var kthread = this.importer.getOrCreateKernelThread(
43 category + ':' + threadName, pid);
44 var slice = new tracing.trace_model.AsyncSlice(
45 category, name, tvcm.ui.getStringColorId(name), ts);
46 slice.startThread = kthread.thread;
48 if (!kthread.openAsyncSlices) {
49 kthread.openAsyncSlices = { };
51 kthread.openAsyncSlices[key] = slice;
54 closeAsyncSlice: function(ts, category, threadName, pid, key, args) {
55 var kthread = this.importer.getOrCreateKernelThread(
56 category + ':' + threadName, pid);
57 if (kthread.openAsyncSlices) {
58 var slice = kthread.openAsyncSlices[key];
60 slice.duration = ts - slice.start;
62 slice.endThread = kthread.thread;
64 new tracing.trace_model.Slice(category, slice.title,
65 slice.colorId, slice.start, slice.args, slice.duration)
67 kthread.thread.asyncSliceGroup.push(slice);
68 delete kthread.openAsyncSlices[key];
74 * Parses events and sets up state in the importer.
76 ext4SyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
77 var event = /dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.
78 exec(eventBase.details);
82 var device = event[1];
83 var inode = parseInt(event[2]);
84 var datasync = event[4] == 1;
85 var key = device + '-' + inode;
86 var action = datasync ? 'fdatasync' : 'fsync';
87 this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
92 ext4SyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
93 var event = /dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);
97 var device = event[1];
98 var inode = parseInt(event[2]);
99 var error = parseInt(event[3]);
100 var key = device + '-' + inode;
101 this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
110 blockRqIssueEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
111 var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
112 '\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);
138 if (event[4] == 'F') {
141 if (event[5] == 'A') {
144 if (event[6] == 'S') {
147 if (event[7] == 'M') {
150 var device = event[1];
151 var sector = parseInt(event[8]);
152 var numSectors = parseInt(event[9]);
153 var key = device + '-' + sector + '-' + numSectors;
154 this.openAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
159 blockRqCompleteEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
160 var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
161 '\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);
165 var device = event[1];
166 var sector = parseInt(event[8]);
167 var numSectors = parseInt(event[9]);
168 var error = parseInt(event[10]);
169 var key = device + '-' + sector + '-' + numSectors;
170 this.closeAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
174 numSectors: numSectors,
181 Parser.registerSubtype(DiskParser);
184 DiskParser: DiskParser