Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / importer / linux_perf / disk_parser.html
1 <!DOCTYPE html>
2 <!--
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.
6 -->
7
8 <link rel="import" href="/tracing/importer/linux_perf/parser.html">
9
10 <script>
11 'use strict';
12
13 /**
14  * @fileoverview Parses filesystem and block device events in the Linux event
15  * trace format.
16  */
17 tvcm.exportTo('tracing.importer.linux_perf', function() {
18
19   var Parser = tracing.importer.linux_perf.Parser;
20
21   /**
22    * Parses linux filesystem and block device trace events.
23    * @constructor
24    */
25   function DiskParser(importer) {
26     Parser.call(this, importer);
27
28     importer.registerEventHandler('f2fs_write_begin',
29         DiskParser.prototype.f2fsWriteBeginEvent.bind(this));
30     importer.registerEventHandler('f2fs_write_end',
31         DiskParser.prototype.f2fsWriteEndEvent.bind(this));
32     importer.registerEventHandler('f2fs_sync_file_enter',
33         DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));
34     importer.registerEventHandler('f2fs_sync_file_exit',
35         DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));
36     importer.registerEventHandler('ext4_sync_file_enter',
37         DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));
38     importer.registerEventHandler('ext4_sync_file_exit',
39         DiskParser.prototype.ext4SyncFileExitEvent.bind(this));
40     importer.registerEventHandler('ext4_da_write_begin',
41         DiskParser.prototype.ext4WriteBeginEvent.bind(this));
42     importer.registerEventHandler('ext4_da_write_end',
43         DiskParser.prototype.ext4WriteEndEvent.bind(this));
44     importer.registerEventHandler('block_rq_issue',
45         DiskParser.prototype.blockRqIssueEvent.bind(this));
46     importer.registerEventHandler('block_rq_complete',
47         DiskParser.prototype.blockRqCompleteEvent.bind(this));
48   }
49
50   DiskParser.prototype = {
51     __proto__: Parser.prototype,
52
53     openAsyncSlice: function(ts, category, threadName, pid, key, name) {
54       var kthread = this.importer.getOrCreateKernelThread(
55           category + ':' + threadName, pid);
56       var slice = new tracing.trace_model.AsyncSlice(
57           category, name, tvcm.ui.getStringColorId(name), ts);
58       slice.startThread = kthread.thread;
59
60       if (!kthread.openAsyncSlices) {
61         kthread.openAsyncSlices = { };
62       }
63       kthread.openAsyncSlices[key] = slice;
64     },
65
66     closeAsyncSlice: function(ts, category, threadName, pid, key, args) {
67       var kthread = this.importer.getOrCreateKernelThread(
68           category + ':' + threadName, pid);
69       if (kthread.openAsyncSlices) {
70         var slice = kthread.openAsyncSlices[key];
71         if (slice) {
72           slice.duration = ts - slice.start;
73           slice.args = args;
74           slice.endThread = kthread.thread;
75           slice.subSlices = [
76             new tracing.trace_model.Slice(category, slice.title,
77                 slice.colorId, slice.start, slice.args, slice.duration)
78           ];
79           kthread.thread.asyncSliceGroup.push(slice);
80           delete kthread.openAsyncSlices[key];
81         }
82       }
83     },
84
85     /**
86      * Parses events and sets up state in the importer.
87      */
88     f2fsWriteBeginEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
89       var event = /dev = \((\d+,\d+)\), ino (\d+), pos (\d+), len (\d+), flags (\d+)/.
90           exec(eventBase.details);
91       if (!event)
92         return false;
93       var device = event[1];
94       var inode = parseInt(event[2]);
95       var pos = parseInt(event[3]);
96       var len = parseInt(event[4]);
97       var key = device + '-' + inode + '-' + pos + '-' + len;
98       this.openAsyncSlice(ts, "f2fs", eventBase.threadName, eventBase.pid,
99           key, "f2fs_write");
100       return true;
101     },
102
103     f2fsWriteEndEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
104       var event = /dev = \((\d+,\d+)\), ino (\d+), pos (\d+), len (\d+), copied (\d+)/.
105           exec(eventBase.details);
106       if (!event)
107         return false;
108
109       var device = event[1];
110       var inode = parseInt(event[2]);
111       var pos = parseInt(event[3]);
112       var len = parseInt(event[4]);
113       var error = parseInt(event[5]) !== len;
114       var key = device + '-' + inode + '-' + pos + '-' + len;
115       this.closeAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid,
116           key, {
117             device: device,
118             inode: inode,
119             error: error
120           });
121       return true;
122     },
123
124     ext4WriteBeginEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
125       var event = /dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.
126           exec(eventBase.details);
127       if (!event)
128         return false;
129       var device = event[1];
130       var inode = parseInt(event[2]);
131       var pos = parseInt(event[3]);
132       var len = parseInt(event[4]);
133       var key = device + '-' + inode + '-' + pos + '-' + len;
134       this.openAsyncSlice(ts, "ext4", eventBase.threadName, eventBase.pid,
135           key, "ext4_write");
136       return true;
137     },
138
139     ext4WriteEndEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
140       var event = /dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.
141           exec(eventBase.details);
142       if (!event)
143         return false;
144
145       var device = event[1];
146       var inode = parseInt(event[2]);
147       var pos = parseInt(event[3]);
148       var len = parseInt(event[4]);
149       var error = parseInt(event[5]) !== len;
150       var key = device + '-' + inode + '-' + pos + '-' + len;
151       this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
152           key, {
153             device: device,
154             inode: inode,
155             error: error
156           });
157       return true;
158     },
159
160     f2fsSyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
161       var event = new RegExp(
162           'dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), ' +
163           'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').
164           exec(eventBase.details);
165       if (!event)
166         return false;
167
168       var device = event[1];
169       var inode = parseInt(event[2]);
170       var key = device + '-' + inode;
171       this.openAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid,
172           key, 'fsync');
173       return true;
174     },
175
176     f2fsSyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
177       var event = new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), ' +
178           'datasync = (\\d+), ret = (\\d+)').
179           exec(eventBase.details.replace("not needed", "not_needed"));
180       if (!event)
181         return false;
182
183       var device = event[1];
184       var inode = parseInt(event[2]);
185       var error = parseInt(event[5]);
186       var key = device + '-' + inode;
187       this.closeAsyncSlice(ts, 'f2fs', eventBase.threadName, eventBase.pid,
188           key, {
189             device: device,
190             inode: inode,
191             error: error
192           });
193       return true;
194     },
195
196     ext4SyncFileEnterEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
197       var event = /dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.
198           exec(eventBase.details);
199       if (!event)
200         return false;
201
202       var device = event[1];
203       var inode = parseInt(event[2]);
204       var datasync = event[4] == 1;
205       var key = device + '-' + inode;
206       var action = datasync ? 'fdatasync' : 'fsync';
207       this.openAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
208           key, action);
209       return true;
210     },
211
212     ext4SyncFileExitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
213       var event = /dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);
214       if (!event)
215         return false;
216
217       var device = event[1];
218       var inode = parseInt(event[2]);
219       var error = parseInt(event[3]);
220       var key = device + '-' + inode;
221       this.closeAsyncSlice(ts, 'ext4', eventBase.threadName, eventBase.pid,
222           key, {
223             device: device,
224             inode: inode,
225             error: error
226           });
227       return true;
228     },
229
230     blockRqIssueEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
231       var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
232           '\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);
233       if (!event)
234         return false;
235
236       var action;
237       switch (event[3]) {
238         case 'D':
239           action = 'discard';
240           break;
241         case 'W':
242           action = 'write';
243           break;
244         case 'R':
245           action = 'read';
246           break;
247         case 'N':
248           action = 'none';
249           break;
250         default:
251           action = 'unknown';
252           break;
253       }
254
255       if (event[2]) {
256         action += ' flush';
257       }
258       if (event[4] == 'F') {
259         action += ' fua';
260       }
261       if (event[5] == 'A') {
262         action += ' ahead';
263       }
264       if (event[6] == 'S') {
265         action += ' sync';
266       }
267       if (event[7] == 'M') {
268         action += ' meta';
269       }
270       var device = event[1];
271       var sector = parseInt(event[8]);
272       var numSectors = parseInt(event[9]);
273       var key = device + '-' + sector + '-' + numSectors;
274       this.openAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
275           key, action);
276       return true;
277     },
278
279     blockRqCompleteEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
280       var event = new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? ' +
281           '\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);
282       if (!event)
283         return false;
284
285       var device = event[1];
286       var sector = parseInt(event[8]);
287       var numSectors = parseInt(event[9]);
288       var error = parseInt(event[10]);
289       var key = device + '-' + sector + '-' + numSectors;
290       this.closeAsyncSlice(ts, 'block', eventBase.threadName, eventBase.pid,
291           key, {
292             device: device,
293             sector: sector,
294             numSectors: numSectors,
295             error: error
296           });
297       return true;
298     }
299   };
300
301   Parser.registerSubtype(DiskParser);
302
303   return {
304     DiskParser: DiskParser
305   };
306 });
307 </script>
308