Home | History | Annotate | Download | only in trace_model
      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  */
     10 base.require('base.guid');
     11 base.require('base.range');
     12 base.require('tracing.trace_model.counter');
     13 base.require('tracing.trace_model.object_collection');
     14 base.require('tracing.trace_model.thread');
     15 base.require('tracing.trace_model_settings');
     16 base.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