blob: fa751414af28d4f9f54980eaf029dac02813ee1a [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/core/trace_model/counter.html">
Chris Craik19832152015-04-16 15:43:38 -07009<link rel="import" href="/core/trace_model/event_container.html">
Chris Craikb122baf2015-03-05 13:58:42 -080010<link rel="import" href="/core/trace_model/object_collection.html">
11<link rel="import" href="/core/trace_model/thread.html">
12<link rel="import" href="/core/trace_model/trace_model_settings.html">
13<link rel="import" href="/base/guid.html">
14<link rel="import" href="/base/range.html">
15
16<script>
17'use strict';
18
19/**
20 * @fileoverview Provides the ProcessBase class.
21 */
22tv.exportTo('tv.c.trace_model', function() {
23
24 var Thread = tv.c.trace_model.Thread;
25 var Counter = tv.c.trace_model.Counter;
26
27 /**
28 * The ProcessBase is a partial base class, upon which Kernel
29 * and Process are built.
30 *
31 * @constructor
32 * @extends {tv.c.trace_model.EventContainer}
33 */
34 function ProcessBase(model) {
35 if (!model)
36 throw new Error('Must provide a model');
Chris Craik19832152015-04-16 15:43:38 -070037 tv.c.trace_model.EventContainer.call(this, model);
Chris Craikb122baf2015-03-05 13:58:42 -080038 this.guid_ = tv.b.GUID.allocate();
39 this.model = model;
40 this.threads = {};
41 this.counters = {};
42 this.objects = new tv.c.trace_model.ObjectCollection(this);
43 this.bounds = new tv.b.Range();
44 this.sortIndex = 0;
45 };
46
47 ProcessBase.compare = function(x, y) {
48 return x.sortIndex - y.sortIndex;
49 };
50
51 ProcessBase.prototype = {
52 __proto__: tv.c.trace_model.EventContainer.prototype,
53
54 /*
55 * @return {Number} A globally unique identifier for this counter.
56 */
57 get guid() {
58 return this.guid_;
59 },
60
61 get stableId() {
62 throw new Error('Not implemented');
63 },
64
Chris Craik44c28202015-05-12 17:25:16 -070065 iterateAllChildEventContainers: function(callback, opt_this) {
66 for (var tid in this.threads)
67 callback.call(opt_this, this.threads[tid]);
68 for (var id in this.counters)
69 callback.call(opt_this, this.counters[id]);
70 callback.call(opt_this, this.objects);
71 },
72
73 iterateAllEventsInThisContainer: function(eventTypePredicate,
74 callback, opt_this) {
75 },
76
77 iterateAllPersistableObjects: function(cb) {
78 cb(this);
79 for (var tid in this.threads)
80 this.threads[tid].iterateAllPersistableObjects(cb);
81 },
82
Chris Craikb122baf2015-03-05 13:58:42 -080083 /**
84 * Gets the number of threads in this process.
85 */
86 get numThreads() {
87 var n = 0;
88 for (var p in this.threads) {
89 n++;
90 }
91 return n;
92 },
93
94 /**
95 * Shifts all the timestamps inside this process forward by the amount
96 * specified.
97 */
98 shiftTimestampsForward: function(amount) {
99 for (var tid in this.threads)
100 this.threads[tid].shiftTimestampsForward(amount);
101 for (var id in this.counters)
102 this.counters[id].shiftTimestampsForward(amount);
103 this.objects.shiftTimestampsForward(amount);
104 },
105
106 /**
107 * Closes any open slices.
108 */
109 autoCloseOpenSlices: function(opt_maxTimestamp) {
110 for (var tid in this.threads) {
111 var thread = this.threads[tid];
112 thread.autoCloseOpenSlices(opt_maxTimestamp);
113 }
114 },
115
116 autoDeleteObjects: function(maxTimestamp) {
117 this.objects.autoDeleteObjects(maxTimestamp);
118 },
119
120 /**
121 * Called by the model after finalizing imports,
122 * but before joining refs.
123 */
124 preInitializeObjects: function() {
125 this.objects.preInitializeAllObjects();
126 },
127
128 /**
129 * Called by the model after joining refs.
130 */
131 initializeObjects: function() {
132 this.objects.initializeAllObjects();
133 },
134
135 /**
136 * Merge slices from the kernel with those from userland for each thread.
137 */
138 mergeKernelWithUserland: function() {
139 for (var tid in this.threads) {
140 var thread = this.threads[tid];
141 thread.mergeKernelWithUserland();
142 }
143 },
144
145 updateBounds: function() {
146 this.bounds.reset();
147 for (var tid in this.threads) {
148 this.threads[tid].updateBounds();
149 this.bounds.addRange(this.threads[tid].bounds);
150 }
151 for (var id in this.counters) {
152 this.counters[id].updateBounds();
153 this.bounds.addRange(this.counters[id].bounds);
154 }
155 this.objects.updateBounds();
156 this.bounds.addRange(this.objects.bounds);
157 },
158
159 addCategoriesToDict: function(categoriesDict) {
160 for (var tid in this.threads)
161 this.threads[tid].addCategoriesToDict(categoriesDict);
162 for (var id in this.counters)
163 categoriesDict[this.counters[id].category] = true;
164 this.objects.addCategoriesToDict(categoriesDict);
165 },
166
Chris Craik44c28202015-05-12 17:25:16 -0700167 findAllThreadsMatching: function(predicate, opt_this) {
168 var threads = [];
169 for (var tid in this.threads) {
170 var thread = this.threads[tid];
171 if (predicate.call(opt_this, thread))
172 threads.push(thread);
173 }
174 return threads;
175 },
176
Chris Craikb122baf2015-03-05 13:58:42 -0800177 /**
178 * @param {String} The name of the thread to find.
179 * @return {Array} An array of all the matched threads.
180 */
181 findAllThreadsNamed: function(name) {
Chris Craik44c28202015-05-12 17:25:16 -0700182 var threads = this.findAllThreadsMatching(function(thread) {
183 if (!thread.name)
184 return false;
185 return thread.name === name;
186 });
187 return threads;
188 },
189
190 findAtMostOneThreadNamed: function(name) {
191 var threads = this.findAllThreadsNamed(name);
192 if (threads.length === 0)
193 return undefined;
194 if (threads.length > 1)
195 throw new Error('Expected no more than one ' + name);
196 return threads[0];
Chris Craikb122baf2015-03-05 13:58:42 -0800197 },
198
199 /**
200 * Removes threads from the process that are fully empty.
201 */
202 pruneEmptyContainers: function() {
203 var threadsToKeep = {};
204 for (var tid in this.threads) {
205 var thread = this.threads[tid];
206 if (!thread.isEmpty)
207 threadsToKeep[tid] = thread;
208 }
209 this.threads = threadsToKeep;
210 },
211
212 /**
213 * @return {TimelineThread} The thread identified by tid on this process,
214 * or undefined if it doesn't exist.
215 */
216 getThread: function(tid) {
217 return this.threads[tid];
218 },
219
220 /**
221 * @return {TimelineThread} The thread identified by tid on this process,
222 * creating it if it doesn't exist.
223 */
224 getOrCreateThread: function(tid) {
225 if (!this.threads[tid])
226 this.threads[tid] = new Thread(this, tid);
227 return this.threads[tid];
228 },
229
230 /**
231 * @return {TimelineCounter} The counter on this process named 'name',
232 * creating it if it doesn't exist.
233 */
234 getOrCreateCounter: function(cat, name) {
235 var id = cat + '.' + name;
236 if (!this.counters[id])
237 this.counters[id] = new Counter(this, id, cat, name);
238 return this.counters[id];
239 },
240
241 getSettingsKey: function() {
242 throw new Error('Not implemented');
243 },
244
245 createSubSlices: function() {
246 for (var tid in this.threads)
247 this.threads[tid].createSubSlices();
Chris Craikb122baf2015-03-05 13:58:42 -0800248 }
249 };
250
251 return {
252 ProcessBase: ProcessBase
253 };
254});
255</script>