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 ProcessBase class. 9 */ 10base.require('base.guid'); 11base.require('base.range'); 12base.require('tracing.trace_model.counter'); 13base.require('tracing.trace_model.object_collection'); 14base.require('tracing.trace_model.thread'); 15base.require('tracing.trace_model_settings'); 16base.exportTo('tracing.trace_model', function() { 17 18 var Thread = tracing.trace_model.Thread; 19 var Counter = tracing.trace_model.Counter; 20 21 /** 22 * The ProcessBase is an partial base class, upon which Kernel 23 * and Process are built. 24 * 25 * @constructor 26 */ 27 function ProcessBase(model) { 28 if (!model) 29 throw new Error('Must provide a model'); 30 this.guid_ = base.GUID.allocate(); 31 this.model = model; 32 this.threads = {}; 33 this.counters = {}; 34 this.objects = new tracing.trace_model.ObjectCollection(this); 35 this.bounds = new base.Range(); 36 this.sortIndex = 0; 37 this.ephemeralSettings = {}; 38 }; 39 40 ProcessBase.compare = function(x, y) { 41 return x.sortIndex - y.sortIndex; 42 }; 43 44 ProcessBase.prototype = { 45 /* 46 * @return {Number} A globally unique identifier for this counter. 47 */ 48 get guid() { 49 return this.guid_; 50 }, 51 52 /** 53 * Gets the number of threads in this process. 54 */ 55 get numThreads() { 56 var n = 0; 57 for (var p in this.threads) { 58 n++; 59 } 60 return n; 61 }, 62 63 toJSON: function() { 64 var obj = new Object(); 65 var keys = Object.keys(this); 66 for (var i = 0; i < keys.length; i++) { 67 var key = keys[i]; 68 if (typeof this[key] == 'function') 69 continue; 70 if (key == 'model') 71 continue; 72 obj[key] = this[key]; 73 } 74 return obj; 75 }, 76 77 /** 78 * Shifts all the timestamps inside this process forward by the amount 79 * specified. 80 */ 81 shiftTimestampsForward: function(amount) { 82 for (var tid in this.threads) 83 this.threads[tid].shiftTimestampsForward(amount); 84 for (var id in this.counters) 85 this.counters[id].shiftTimestampsForward(amount); 86 this.objects.shiftTimestampsForward(amount); 87 }, 88 89 /** 90 * Closes any open slices. 91 */ 92 autoCloseOpenSlices: function(opt_maxTimestamp) { 93 for (var tid in this.threads) { 94 var thread = this.threads[tid]; 95 thread.autoCloseOpenSlices(opt_maxTimestamp); 96 } 97 }, 98 99 autoDeleteObjects: function(maxTimestamp) { 100 this.objects.autoDeleteObjects(maxTimestamp); 101 }, 102 103 /** 104 * Called by the model after finalizing imports, 105 * but before joining refs. 106 */ 107 preInitializeObjects: function() { 108 this.objects.preInitializeAllObjects(); 109 }, 110 111 /** 112 * Called by the model after joining refs. 113 */ 114 initializeObjects: function() { 115 this.objects.initializeAllObjects(); 116 }, 117 118 /** 119 * Merge slices from the kernel with those from userland for each thread. 120 */ 121 mergeKernelWithUserland: function() { 122 for (var tid in this.threads) { 123 var thread = this.threads[tid]; 124 thread.mergeKernelWithUserland(); 125 } 126 }, 127 128 updateBounds: function() { 129 this.bounds.reset(); 130 for (var tid in this.threads) { 131 this.threads[tid].updateBounds(); 132 this.bounds.addRange(this.threads[tid].bounds); 133 } 134 for (var id in this.counters) { 135 this.counters[id].updateBounds(); 136 this.bounds.addRange(this.counters[id].bounds); 137 } 138 this.objects.updateBounds(); 139 this.bounds.addRange(this.objects.bounds); 140 }, 141 142 addCategoriesToDict: function(categoriesDict) { 143 for (var tid in this.threads) 144 this.threads[tid].addCategoriesToDict(categoriesDict); 145 for (var id in this.counters) 146 categoriesDict[this.counters[id].category] = true; 147 this.objects.addCategoriesToDict(categoriesDict); 148 }, 149 150 /** 151 * @param {String} The name of the thread to find. 152 * @return {Array} An array of all the matched threads. 153 */ 154 findAllThreadsNamed: function(name) { 155 var namedThreads = []; 156 for (var tid in this.threads) { 157 var thread = this.threads[tid]; 158 if (thread.name == name) 159 namedThreads.push(thread); 160 } 161 return namedThreads; 162 }, 163 164 /** 165 * Removes threads from the process that are fully empty. 166 */ 167 pruneEmptyContainers: function() { 168 var threadsToKeep = {}; 169 for (var tid in this.threads) { 170 var thread = this.threads[tid]; 171 if (!thread.isEmpty) 172 threadsToKeep[tid] = thread; 173 } 174 this.threads = threadsToKeep; 175 }, 176 177 /** 178 * @return {TimlineThread} The thread identified by tid on this process, 179 * creating it if it doesn't exist. 180 */ 181 getOrCreateThread: function(tid) { 182 if (!this.threads[tid]) 183 this.threads[tid] = new Thread(this, tid); 184 return this.threads[tid]; 185 }, 186 187 /** 188 * @return {TimlineCounter} The counter on this process named 'name', 189 * creating it if it doesn't exist. 190 */ 191 getOrCreateCounter: function(cat, name) { 192 var id = cat + '.' + name; 193 if (!this.counters[id]) 194 this.counters[id] = new Counter(this, id, cat, name); 195 return this.counters[id]; 196 }, 197 198 getSettingsKey: function() { 199 throw new Error('Not implemented'); 200 } 201 }; 202 203 return { 204 ProcessBase: ProcessBase 205 }; 206}); 207