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