Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / trace_model / cpu.js
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 Provides the Cpu class.
9  */
10 tvcm.require('tvcm.range');
11 tvcm.require('tracing.trace_model.slice');
12 tvcm.require('tracing.trace_model.counter');
13 tvcm.exportTo('tracing.trace_model', function() {
14
15   var Counter = tracing.trace_model.Counter;
16   var Slice = tracing.trace_model.Slice;
17
18   /**
19    * A CpuSlice represents a slice of time on a CPU.
20    *
21    * @constructor
22    */
23   function CpuSlice(cat, title, colorId, start, args, opt_duration) {
24     Slice.apply(this, arguments);
25     this.threadThatWasRunning = undefined;
26     this.cpu = undefined;
27   }
28
29   CpuSlice.prototype = {
30     __proto__: Slice.prototype,
31
32     get analysisTypeName() {
33       return 'tracing.analysis.CpuSlice';
34     },
35
36     toJSON: function() {
37       var obj = new Object();
38       var keys = Object.keys(this);
39       for (var i = 0; i < keys.length; i++) {
40         var key = keys[i];
41         if (typeof this[key] == 'function')
42           continue;
43         if (key == 'cpu' || key == 'threadThatWasRunning') {
44           if (this[key])
45             obj[key] = this[key].guid;
46           continue;
47         }
48         obj[key] = this[key];
49       }
50       return obj;
51     },
52
53     getAssociatedTimeslice: function() {
54       if (!this.threadThatWasRunning)
55         return undefined;
56       var timeSlices = this.threadThatWasRunning.timeSlices;
57       for (var i = 0; i < timeSlices.length; i++) {
58         var timeSlice = timeSlices[i];
59         if (timeSlice.start !== this.start)
60           continue;
61         if (timeSlice.duration !== this.duration)
62           continue;
63         return timeSlice;
64       }
65       return undefined;
66     }
67   };
68
69   /**
70    * A ThreadTimeSlice is a slice of time on a specific thread where that thread
71    * was running on a specific CPU, or in a specific sleep state.
72    *
73    * As a thread switches moves through its life, it sometimes goes to sleep and
74    * can't run. Other times, its runnable but isn't actually assigned to a CPU.
75    * Finally, sometimes it gets put on a CPU to actually execute. Each of these
76    * states is represented by a ThreadTimeSlice:
77    *
78    *   Sleeping or runnable: cpuOnWhichThreadWasRunning is undefined
79    *   Running:  cpuOnWhichThreadWasRunning is set.
80    *
81    * @constructor
82    */
83   function ThreadTimeSlice(
84       thread, cat, title, colorId, start, args, opt_duration) {
85     Slice.call(this, cat, title, colorId, start, args, opt_duration);
86     this.thread = thread;
87     this.cpuOnWhichThreadWasRunning = undefined;
88   }
89
90   ThreadTimeSlice.prototype = {
91     __proto__: Slice.prototype,
92
93     get analysisTypeName() {
94       return 'tracing.analysis.ThreadTimeSlice';
95     },
96
97     toJSON: function() {
98       var obj = new Object();
99       var keys = Object.keys(this);
100       for (var i = 0; i < keys.length; i++) {
101         var key = keys[i];
102         if (typeof this[key] == 'function')
103           continue;
104         if (key == 'thread' || key == 'cpuOnWhichThreadWasRunning') {
105           if (this[key])
106             obj[key] = this[key].guid;
107           continue;
108         }
109         obj[key] = this[key];
110       }
111       return obj;
112     },
113
114     getAssociatedCpuSlice: function() {
115       if (!this.cpuOnWhichThreadWasRunning)
116         return undefined;
117       var cpuSlices = this.cpuOnWhichThreadWasRunning.slices;
118       for (var i = 0; i < cpuSlices.length; i++) {
119         var cpuSlice = cpuSlices[i];
120         if (cpuSlice.start !== this.start)
121           continue;
122         if (cpuSlice.duration !== this.duration)
123           continue;
124         return cpuSlice;
125       }
126       return undefined;
127     },
128
129     getCpuSliceThatTookCpu: function() {
130       if (this.cpuOnWhichThreadWasRunning)
131         return undefined;
132       var curIndex = this.thread.indexOfTimeSlice(this);
133       var cpuSliceWhenLastRunning;
134       while (curIndex >= 0) {
135         var curSlice = this.thread.timeSlices[curIndex];
136         if (!curSlice.cpuOnWhichThreadWasRunning) {
137           curIndex--;
138           continue;
139         }
140         cpuSliceWhenLastRunning = curSlice.getAssociatedCpuSlice();
141         break;
142       }
143       if (!cpuSliceWhenLastRunning)
144         return undefined;
145
146       var cpu = cpuSliceWhenLastRunning.cpu;
147       var indexOfSliceOnCpuWhenLastRunning =
148           cpu.indexOf(cpuSliceWhenLastRunning);
149       var nextRunningSlice = cpu.slices[indexOfSliceOnCpuWhenLastRunning + 1];
150       if (!nextRunningSlice)
151         return undefined;
152       if (Math.abs(nextRunningSlice.start - cpuSliceWhenLastRunning.end) <
153           0.00001)
154         return nextRunningSlice;
155       return undefined;
156     }
157   };
158
159   /**
160    * The Cpu represents a Cpu from the kernel's point of view.
161    * @constructor
162    */
163   function Cpu(number) {
164     this.cpuNumber = number;
165     this.slices = [];
166     this.counters = {};
167     this.bounds = new tvcm.Range();
168   };
169
170   Cpu.prototype = {
171     /**
172      * @return {TimelineCounter} The counter on this process named 'name',
173      * creating it if it doesn't exist.
174      */
175     getOrCreateCounter: function(cat, name) {
176       var id;
177       if (cat.length)
178         id = cat + '.' + name;
179       else
180         id = name;
181       if (!this.counters[id])
182         this.counters[id] = new Counter(this, id, cat, name);
183       return this.counters[id];
184     },
185
186     /**
187      * Shifts all the timestamps inside this CPU forward by the amount
188      * specified.
189      */
190     shiftTimestampsForward: function(amount) {
191       for (var sI = 0; sI < this.slices.length; sI++)
192         this.slices[sI].start = (this.slices[sI].start + amount);
193       for (var id in this.counters)
194         this.counters[id].shiftTimestampsForward(amount);
195     },
196
197     /**
198      * Updates the range based on the current slices attached to the cpu.
199      */
200     updateBounds: function() {
201       this.bounds.reset();
202       if (this.slices.length) {
203         this.bounds.addValue(this.slices[0].start);
204         this.bounds.addValue(this.slices[this.slices.length - 1].end);
205       }
206       for (var id in this.counters) {
207         this.counters[id].updateBounds();
208         this.bounds.addRange(this.counters[id].bounds);
209       }
210     },
211
212     addCategoriesToDict: function(categoriesDict) {
213       for (var i = 0; i < this.slices.length; i++)
214         categoriesDict[this.slices[i].category] = true;
215       for (var id in this.counters)
216         categoriesDict[this.counters[id].category] = true;
217     },
218
219     get userFriendlyName() {
220       return 'CPU ' + this.cpuNumber;
221     },
222
223     /*
224      * Returns the index of the slice in the CPU's slices, or undefined.
225      */
226     indexOf: function(cpuSlice) {
227       var i = tvcm.findLowIndexInSortedArray(
228           this.slices,
229           function(slice) { return slice.start; },
230           cpuSlice.start);
231       if (this.slices[i] !== cpuSlice)
232         return undefined;
233       return i;
234     },
235
236     iterateAllEvents: function(callback, opt_this) {
237       this.slices.forEach(callback, opt_this);
238
239       for (var id in this.counters)
240         this.counters[id].iterateAllEvents(callback, opt_this);
241     }
242   };
243
244   /**
245    * Comparison between processes that orders by cpuNumber.
246    */
247   Cpu.compare = function(x, y) {
248     return x.cpuNumber - y.cpuNumber;
249   };
250
251
252   return {
253     Cpu: Cpu,
254     CpuSlice: CpuSlice,
255     ThreadTimeSlice: ThreadTimeSlice
256   };
257 });