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.
8 * @fileoverview Provides the Cpu class.
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() {
15 var Counter = tracing.trace_model.Counter;
16 var Slice = tracing.trace_model.Slice;
19 * A CpuSlice represents a slice of time on a CPU.
23 function CpuSlice(cat, title, colorId, start, args, opt_duration) {
24 Slice.apply(this, arguments);
25 this.threadThatWasRunning = undefined;
29 CpuSlice.prototype = {
30 __proto__: Slice.prototype,
32 get analysisTypeName() {
33 return 'tracing.analysis.CpuSlice';
37 var obj = new Object();
38 var keys = Object.keys(this);
39 for (var i = 0; i < keys.length; i++) {
41 if (typeof this[key] == 'function')
43 if (key == 'cpu' || key == 'threadThatWasRunning') {
45 obj[key] = this[key].guid;
53 getAssociatedTimeslice: function() {
54 if (!this.threadThatWasRunning)
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)
61 if (timeSlice.duration !== this.duration)
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.
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:
78 * Sleeping or runnable: cpuOnWhichThreadWasRunning is undefined
79 * Running: cpuOnWhichThreadWasRunning is set.
83 function ThreadTimeSlice(
84 thread, cat, title, colorId, start, args, opt_duration) {
85 Slice.call(this, cat, title, colorId, start, args, opt_duration);
87 this.cpuOnWhichThreadWasRunning = undefined;
90 ThreadTimeSlice.prototype = {
91 __proto__: Slice.prototype,
93 get analysisTypeName() {
94 return 'tracing.analysis.ThreadTimeSlice';
98 var obj = new Object();
99 var keys = Object.keys(this);
100 for (var i = 0; i < keys.length; i++) {
102 if (typeof this[key] == 'function')
104 if (key == 'thread' || key == 'cpuOnWhichThreadWasRunning') {
106 obj[key] = this[key].guid;
109 obj[key] = this[key];
114 getAssociatedCpuSlice: function() {
115 if (!this.cpuOnWhichThreadWasRunning)
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)
122 if (cpuSlice.duration !== this.duration)
129 getCpuSliceThatTookCpu: function() {
130 if (this.cpuOnWhichThreadWasRunning)
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) {
140 cpuSliceWhenLastRunning = curSlice.getAssociatedCpuSlice();
143 if (!cpuSliceWhenLastRunning)
146 var cpu = cpuSliceWhenLastRunning.cpu;
147 var indexOfSliceOnCpuWhenLastRunning =
148 cpu.indexOf(cpuSliceWhenLastRunning);
149 var nextRunningSlice = cpu.slices[indexOfSliceOnCpuWhenLastRunning + 1];
150 if (!nextRunningSlice)
152 if (Math.abs(nextRunningSlice.start - cpuSliceWhenLastRunning.end) <
154 return nextRunningSlice;
160 * The Cpu represents a Cpu from the kernel's point of view.
163 function Cpu(number) {
164 this.cpuNumber = number;
167 this.bounds = new tvcm.Range();
172 * @return {TimelineCounter} The counter on this process named 'name',
173 * creating it if it doesn't exist.
175 getOrCreateCounter: function(cat, name) {
178 id = cat + '.' + name;
181 if (!this.counters[id])
182 this.counters[id] = new Counter(this, id, cat, name);
183 return this.counters[id];
187 * Shifts all the timestamps inside this CPU forward by the amount
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);
198 * Updates the range based on the current slices attached to the cpu.
200 updateBounds: function() {
202 if (this.slices.length) {
203 this.bounds.addValue(this.slices[0].start);
204 this.bounds.addValue(this.slices[this.slices.length - 1].end);
206 for (var id in this.counters) {
207 this.counters[id].updateBounds();
208 this.bounds.addRange(this.counters[id].bounds);
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;
219 get userFriendlyName() {
220 return 'CPU ' + this.cpuNumber;
224 * Returns the index of the slice in the CPU's slices, or undefined.
226 indexOf: function(cpuSlice) {
227 var i = tvcm.findLowIndexInSortedArray(
229 function(slice) { return slice.start; },
231 if (this.slices[i] !== cpuSlice)
236 iterateAllEvents: function(callback, opt_this) {
237 this.slices.forEach(callback, opt_this);
239 for (var id in this.counters)
240 this.counters[id].iterateAllEvents(callback, opt_this);
245 * Comparison between processes that orders by cpuNumber.
247 Cpu.compare = function(x, y) {
248 return x.cpuNumber - y.cpuNumber;
255 ThreadTimeSlice: ThreadTimeSlice