Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / src / tracing / importer / linux_perf / disk_parser.js
1 // Copyright (c) 2013 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 filesystem and block device events in the Linux event
9  * trace format.
10  */
11 tvcm.require('tracing.importer.linux_perf.parser');
12 tvcm.exportTo('tracing.importer.linux_perf', function() {
13
14   var Parser = tracing.importer.linux_perf.Parser;
15
16   /**
17    * Parses linux filesystem and block device trace events.
18    * @constructor
19    */
20   function DiskParser(importer) {
21     Parser.call(this, importer);
22
23     importer.registerEventHandler('ext4_sync_file_enter',
24         DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));
25     importer.registerEventHandler('ext4_sync_file_exit',
26         DiskParser.prototype.ext4SyncFileExitEvent.bind(this));
27     importer.registerEventHandler('block_rq_issue',
28         DiskParser.prototype.blockRqIssueEvent.bind(this));
29     importer.registerEventHandler('block_rq_complete',
30         DiskParser.prototype.blockRqCompleteEvent.bind(this));
31   }
32
33   DiskParser.prototype = {
34     __proto__: Parser.prototype,
35
36     openAsyncSlice: function(ts, category, threadName, pid, key, name) {
37       var kthread = this.importer.getOrCreateKernelThread(
38           category + ':' + threadName, pid);
39       var slice = new tracing.trace_model.AsyncSlice(
40           category, name, tracing.getStringColorId(name), ts);
41       slice.startThread = kthread.thread;
42
43       if (!kthread.openAsyncSlices) {
44         kthread.openAsyncSlices = { };
45       }
46       kthread.openAsyncSlices[key] = slice;
47     },
48
49     closeAsyncSlice: function(ts, category, threadName, pid, key, args) {
50       var kthread = this.importer.getOrCreateKernelThread(
51           category + ':' + threadName, pid);
52       if (kthread.openAsyncSlices) {
53         var slice = kthread.openAsyncSlices[key];
54         if (slice) {
55           slice.duration = ts - slice.start;
56           slice.args = args;
57           slice.endThread = kthread.thread;
58           slice.subSlices = [
59             new tracing.trace_model.Slice(category, slice.title,
60                 slice.colorId, slice.start, slice.args, slice.duration)
61           ];
62           kthread.thread.asyncSliceGroup.push(slice);
63           delete kthread.openAsyncSlices[key];
64         }
65       }
66     },
67
68     /**
69      * Parses events and sets up state in the importer.
70      */
71     ext4SyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
72       var event = /dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.
73           exec(eventBase.details);
74       if (!event)
75         return false;
76
77       var device = event[1];
78       var inode = parseInt(event[2]);
79       var datasync = event[4] == 1;
80       var key = device + '-' + inode;
81       var action = datasync ? 'fdatasync' : 'fsync';
82       this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
83           key, action);
84       return true;
85     },
86
87     ext4SyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
88       var event = /dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);
89       if (!event)
90         return false;
91
92       var device = event[1];
93       var inode = parseInt(event[2]);
94       var error = parseInt(event[3]);
95       var key = device + '-' + inode;
96       this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
97           key, {
98             device: device,
99             inode: inode,
100             error: error
101           });
102       return true;
103     },
104
105     blockRqIssueEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
106       var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
107           '\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);
108       if (!event)
109         return false;
110
111       var action;
112       switch (event[3]) {
113         case 'D':
114           action = 'discard';
115           break;
116         case 'W':
117           action = 'write';
118           break;
119         case 'R':
120           action = 'read';
121           break;
122         case 'N':
123           action = 'none';
124           break;
125         default:
126           action = 'unknown';
127           break;
128       }
129
130       if (event[2]) {
131         action += ' flush';
132       }
133       if (event[4] == 'F') {
134         action += ' fua';
135       }
136       if (event[5] == 'A') {
137         action += ' ahead';
138       }
139       if (event[6] == 'S') {
140         action += ' sync';
141       }
142       if (event[7] == 'M') {
143         action += ' meta';
144       }
145       var device = event[1];
146       var sector = parseInt(event[8]);
147       var numSectors = parseInt(event[9]);
148       var key = device + '-' + sector + '-' + numSectors;
149       this.openAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
150           key, action);
151       return true;
152     },
153
154     blockRqCompleteEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
155       var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
156           '\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);
157       if (!event)
158         return false;
159
160       var device = event[1];
161       var sector = parseInt(event[8]);
162       var numSectors = parseInt(event[9]);
163       var error = parseInt(event[10]);
164       var key = device + '-' + sector + '-' + numSectors;
165       this.closeAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
166           key, {
167             device: device,
168             sector: sector,
169             numSectors: numSectors,
170             error: error
171           });
172       return true;
173     }
174   };
175
176   Parser.registerSubtype(DiskParser);
177
178   return {
179     DiskParser: DiskParser
180   };
181 });