Javascript  |  131行  |  4.26 KB

// Copyright (c) 2012 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.

/**
 * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format.
 */
base.require('linux_perf_parser');
base.exportTo('tracing', function() {

  var LinuxPerfParser = tracing.LinuxPerfParser;

  /**
   * Parses Mali DDK/kernel trace events.
   * @constructor
   */
  function LinuxPerfMaliParser(importer) {
    LinuxPerfParser.call(this, importer);

    // kernel events
    importer.registerEventHandler('mali_dvfs_event',
        LinuxPerfMaliParser.prototype.dvfsEventEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_clock',
        LinuxPerfMaliParser.prototype.dvfsSetClockEvent.bind(this));
    importer.registerEventHandler('mali_dvfs_set_voltage',
        LinuxPerfMaliParser.prototype.dvfsSetVoltageEvent.bind(this));

    // DDK events (from X server)
    importer.registerEventHandler('tracing_mark_write:mali_driver',
        LinuxPerfMaliParser.prototype.maliDDKEvent.bind(this));
  }

  LinuxPerfMaliParser.prototype = {
    __proto__: LinuxPerfParser.prototype,

    maliDDKOpenSlice: function(pid, ts, func, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      kthread.thread.beginSlice('gpu-driver', func, ts,
                                { 'blockinfo': blockinfo });
    },

    maliDDKCloseSlice: function(pid, ts, args, blockinfo) {
      var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
                                                          'mali_ddk');
      var thread = kthread.thread;
      if (!thread.openSliceCount) {
        this.importer.importError('maliDDKCloseSlice w/o matching OpenSlice');
        return;
      }
      thread.endSlice(ts);
    },

    /**
     * Parses maliDDK events and sets up state in the importer.
     * events will come in pairs with a cros_trace_print_enter
     * like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_enter:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     * gles2_texturep_upload_2d
     *
     * and a cros_trace_print_exit like this:
     *
     * tracing_mark_write: mali_driver: cros_trace_print_exit:
     * gles/src/texture/mali_gles_texture_slave.c1505:
     */
    maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var maliEvent =
          /^s*(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/.exec(eventBase[2]);
      switch (maliEvent[1]) {
        case 'cros_trace_print_enter':
          this.maliDDKOpenSlice(pid, ts, maliEvent[3], maliEvent[2]);
          break;
        case 'cros_trace_print_exit':
          this.maliDDKCloseSlice(pid, ts, [], maliEvent[2]);
      }
      return true;
    },

    /*
     * Kernel event support.
     */

    dvfsSample: function(counterName, seriesName, ts, value) {
      // NB: record all data on cpu 0; cpuNumber is not meaningful
      var targetCpu = this.importer.getOrCreateCpuState(0);
      var counter = targetCpu.cpu.getOrCreateCounter('', counterName);
      if (counter.numSeries == 0) {
        counter.seriesNames.push(seriesName);
        counter.seriesColors.push(tracing.getStringColorId(counter.name));
      }
      counter.timestamps.push(ts);
      counter.samples.push(value);
    },

    dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /utilization=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]);
      return true;
    },

    dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /frequency=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]);
      return true;
    },

    dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = /voltage=(\d+)/.exec(eventBase[5]);
      if (!event)
        return false;

      this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]);
      return true;
    }
  };

  LinuxPerfParser.registerSubtype(LinuxPerfMaliParser);

  return {
    LinuxPerfMaliParser: LinuxPerfMaliParser
  };
});