| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="/core/trace_model/counter.html"> |
| <link rel="import" href="/core/trace_model/event_container.html"> |
| <link rel="import" href="/core/trace_model/object_collection.html"> |
| <link rel="import" href="/core/trace_model/thread.html"> |
| <link rel="import" href="/core/trace_model/trace_model_settings.html"> |
| <link rel="import" href="/base/guid.html"> |
| <link rel="import" href="/base/range.html"> |
| |
| <script> |
| 'use strict'; |
| |
| /** |
| * @fileoverview Provides the ProcessBase class. |
| */ |
| tv.exportTo('tv.c.trace_model', function() { |
| |
| var Thread = tv.c.trace_model.Thread; |
| var Counter = tv.c.trace_model.Counter; |
| |
| /** |
| * The ProcessBase is a partial base class, upon which Kernel |
| * and Process are built. |
| * |
| * @constructor |
| * @extends {tv.c.trace_model.EventContainer} |
| */ |
| function ProcessBase(model) { |
| if (!model) |
| throw new Error('Must provide a model'); |
| tv.c.trace_model.EventContainer.call(this, model); |
| this.guid_ = tv.b.GUID.allocate(); |
| this.model = model; |
| this.threads = {}; |
| this.counters = {}; |
| this.objects = new tv.c.trace_model.ObjectCollection(this); |
| this.bounds = new tv.b.Range(); |
| this.sortIndex = 0; |
| }; |
| |
| ProcessBase.compare = function(x, y) { |
| return x.sortIndex - y.sortIndex; |
| }; |
| |
| ProcessBase.prototype = { |
| __proto__: tv.c.trace_model.EventContainer.prototype, |
| |
| /* |
| * @return {Number} A globally unique identifier for this counter. |
| */ |
| get guid() { |
| return this.guid_; |
| }, |
| |
| get stableId() { |
| throw new Error('Not implemented'); |
| }, |
| |
| iterateAllChildEventContainers: function(callback, opt_this) { |
| for (var tid in this.threads) |
| callback.call(opt_this, this.threads[tid]); |
| for (var id in this.counters) |
| callback.call(opt_this, this.counters[id]); |
| callback.call(opt_this, this.objects); |
| }, |
| |
| iterateAllEventsInThisContainer: function(eventTypePredicate, |
| callback, opt_this) { |
| }, |
| |
| iterateAllPersistableObjects: function(cb) { |
| cb(this); |
| for (var tid in this.threads) |
| this.threads[tid].iterateAllPersistableObjects(cb); |
| }, |
| |
| /** |
| * Gets the number of threads in this process. |
| */ |
| get numThreads() { |
| var n = 0; |
| for (var p in this.threads) { |
| n++; |
| } |
| return n; |
| }, |
| |
| /** |
| * Shifts all the timestamps inside this process forward by the amount |
| * specified. |
| */ |
| shiftTimestampsForward: function(amount) { |
| for (var tid in this.threads) |
| this.threads[tid].shiftTimestampsForward(amount); |
| for (var id in this.counters) |
| this.counters[id].shiftTimestampsForward(amount); |
| this.objects.shiftTimestampsForward(amount); |
| }, |
| |
| /** |
| * Closes any open slices. |
| */ |
| autoCloseOpenSlices: function(opt_maxTimestamp) { |
| for (var tid in this.threads) { |
| var thread = this.threads[tid]; |
| thread.autoCloseOpenSlices(opt_maxTimestamp); |
| } |
| }, |
| |
| autoDeleteObjects: function(maxTimestamp) { |
| this.objects.autoDeleteObjects(maxTimestamp); |
| }, |
| |
| /** |
| * Called by the model after finalizing imports, |
| * but before joining refs. |
| */ |
| preInitializeObjects: function() { |
| this.objects.preInitializeAllObjects(); |
| }, |
| |
| /** |
| * Called by the model after joining refs. |
| */ |
| initializeObjects: function() { |
| this.objects.initializeAllObjects(); |
| }, |
| |
| /** |
| * Merge slices from the kernel with those from userland for each thread. |
| */ |
| mergeKernelWithUserland: function() { |
| for (var tid in this.threads) { |
| var thread = this.threads[tid]; |
| thread.mergeKernelWithUserland(); |
| } |
| }, |
| |
| updateBounds: function() { |
| this.bounds.reset(); |
| for (var tid in this.threads) { |
| this.threads[tid].updateBounds(); |
| this.bounds.addRange(this.threads[tid].bounds); |
| } |
| for (var id in this.counters) { |
| this.counters[id].updateBounds(); |
| this.bounds.addRange(this.counters[id].bounds); |
| } |
| this.objects.updateBounds(); |
| this.bounds.addRange(this.objects.bounds); |
| }, |
| |
| addCategoriesToDict: function(categoriesDict) { |
| for (var tid in this.threads) |
| this.threads[tid].addCategoriesToDict(categoriesDict); |
| for (var id in this.counters) |
| categoriesDict[this.counters[id].category] = true; |
| this.objects.addCategoriesToDict(categoriesDict); |
| }, |
| |
| findAllThreadsMatching: function(predicate, opt_this) { |
| var threads = []; |
| for (var tid in this.threads) { |
| var thread = this.threads[tid]; |
| if (predicate.call(opt_this, thread)) |
| threads.push(thread); |
| } |
| return threads; |
| }, |
| |
| /** |
| * @param {String} The name of the thread to find. |
| * @return {Array} An array of all the matched threads. |
| */ |
| findAllThreadsNamed: function(name) { |
| var threads = this.findAllThreadsMatching(function(thread) { |
| if (!thread.name) |
| return false; |
| return thread.name === name; |
| }); |
| return threads; |
| }, |
| |
| findAtMostOneThreadNamed: function(name) { |
| var threads = this.findAllThreadsNamed(name); |
| if (threads.length === 0) |
| return undefined; |
| if (threads.length > 1) |
| throw new Error('Expected no more than one ' + name); |
| return threads[0]; |
| }, |
| |
| /** |
| * Removes threads from the process that are fully empty. |
| */ |
| pruneEmptyContainers: function() { |
| var threadsToKeep = {}; |
| for (var tid in this.threads) { |
| var thread = this.threads[tid]; |
| if (!thread.isEmpty) |
| threadsToKeep[tid] = thread; |
| } |
| this.threads = threadsToKeep; |
| }, |
| |
| /** |
| * @return {TimelineThread} The thread identified by tid on this process, |
| * or undefined if it doesn't exist. |
| */ |
| getThread: function(tid) { |
| return this.threads[tid]; |
| }, |
| |
| /** |
| * @return {TimelineThread} The thread identified by tid on this process, |
| * creating it if it doesn't exist. |
| */ |
| getOrCreateThread: function(tid) { |
| if (!this.threads[tid]) |
| this.threads[tid] = new Thread(this, tid); |
| return this.threads[tid]; |
| }, |
| |
| /** |
| * @return {TimelineCounter} The counter on this process named 'name', |
| * creating it if it doesn't exist. |
| */ |
| getOrCreateCounter: function(cat, name) { |
| var id = cat + '.' + name; |
| if (!this.counters[id]) |
| this.counters[id] = new Counter(this, id, cat, name); |
| return this.counters[id]; |
| }, |
| |
| getSettingsKey: function() { |
| throw new Error('Not implemented'); |
| }, |
| |
| createSubSlices: function() { |
| for (var tid in this.threads) |
| this.threads[tid].createSubSlices(); |
| } |
| }; |
| |
| return { |
| ProcessBase: ProcessBase |
| }; |
| }); |
| </script> |