Home | History | Annotate | Download | only in src
      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 /**
      6  * @fileoverview Parses Mali DDK/kernel events in the Linux event trace format.
      7  */
      8 base.require('linux_perf_parser');
      9 base.exportTo('tracing', function() {
     10 
     11   var LinuxPerfParser = tracing.LinuxPerfParser;
     12 
     13   /**
     14    * Parses Mali DDK/kernel trace events.
     15    * @constructor
     16    */
     17   function LinuxPerfMaliParser(importer) {
     18     LinuxPerfParser.call(this, importer);
     19 
     20     // kernel events
     21     importer.registerEventHandler('mali_dvfs_event',
     22         LinuxPerfMaliParser.prototype.dvfsEventEvent.bind(this));
     23     importer.registerEventHandler('mali_dvfs_set_clock',
     24         LinuxPerfMaliParser.prototype.dvfsSetClockEvent.bind(this));
     25     importer.registerEventHandler('mali_dvfs_set_voltage',
     26         LinuxPerfMaliParser.prototype.dvfsSetVoltageEvent.bind(this));
     27 
     28     // DDK events (from X server)
     29     importer.registerEventHandler('tracing_mark_write:mali_driver',
     30         LinuxPerfMaliParser.prototype.maliDDKEvent.bind(this));
     31   }
     32 
     33   LinuxPerfMaliParser.prototype = {
     34     __proto__: LinuxPerfParser.prototype,
     35 
     36     maliDDKOpenSlice: function(pid, ts, func, blockinfo) {
     37       var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
     38                                                           'mali_ddk');
     39       kthread.thread.beginSlice('gpu-driver', func, ts,
     40                                 { 'blockinfo': blockinfo });
     41     },
     42 
     43     maliDDKCloseSlice: function(pid, ts, args, blockinfo) {
     44       var kthread = this.importer.getOrCreateKernelThread('mali_ddk', pid,
     45                                                           'mali_ddk');
     46       var thread = kthread.thread;
     47       if (!thread.openSliceCount) {
     48         this.importer.importError('maliDDKCloseSlice w/o matching OpenSlice');
     49         return;
     50       }
     51       thread.endSlice(ts);
     52     },
     53 
     54     /**
     55      * Parses maliDDK events and sets up state in the importer.
     56      * events will come in pairs with a cros_trace_print_enter
     57      * like this:
     58      *
     59      * tracing_mark_write: mali_driver: cros_trace_print_enter:
     60      * gles/src/texture/mali_gles_texture_slave.c1505:
     61      * gles2_texturep_upload_2d
     62      *
     63      * and a cros_trace_print_exit like this:
     64      *
     65      * tracing_mark_write: mali_driver: cros_trace_print_exit:
     66      * gles/src/texture/mali_gles_texture_slave.c1505:
     67      */
     68     maliDDKEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
     69       var maliEvent =
     70           /^s*(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/.exec(eventBase[2]);
     71       switch (maliEvent[1]) {
     72         case 'cros_trace_print_enter':
     73           this.maliDDKOpenSlice(pid, ts, maliEvent[3], maliEvent[2]);
     74           break;
     75         case 'cros_trace_print_exit':
     76           this.maliDDKCloseSlice(pid, ts, [], maliEvent[2]);
     77       }
     78       return true;
     79     },
     80 
     81     /*
     82      * Kernel event support.
     83      */
     84 
     85     dvfsSample: function(counterName, seriesName, ts, value) {
     86       // NB: record all data on cpu 0; cpuNumber is not meaningful
     87       var targetCpu = this.importer.getOrCreateCpuState(0);
     88       var counter = targetCpu.cpu.getOrCreateCounter('', counterName);
     89       if (counter.numSeries == 0) {
     90         counter.seriesNames.push(seriesName);
     91         counter.seriesColors.push(tracing.getStringColorId(counter.name));
     92       }
     93       counter.timestamps.push(ts);
     94       counter.samples.push(value);
     95     },
     96 
     97     dvfsEventEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
     98       var event = /utilization=(\d+)/.exec(eventBase[5]);
     99       if (!event)
    100         return false;
    101 
    102       this.dvfsSample('DVFS Utilization', 'utilization', ts, event[1]);
    103       return true;
    104     },
    105 
    106     dvfsSetClockEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
    107       var event = /frequency=(\d+)/.exec(eventBase[5]);
    108       if (!event)
    109         return false;
    110 
    111       this.dvfsSample('DVFS Frequency', 'frequency', ts, event[1]);
    112       return true;
    113     },
    114 
    115     dvfsSetVoltageEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
    116       var event = /voltage=(\d+)/.exec(eventBase[5]);
    117       if (!event)
    118         return false;
    119 
    120       this.dvfsSample('DVFS Voltage', 'voltage', ts, event[1]);
    121       return true;
    122     }
    123   };
    124 
    125   LinuxPerfParser.registerSubtype(LinuxPerfMaliParser);
    126 
    127   return {
    128     LinuxPerfMaliParser: LinuxPerfMaliParser
    129   };
    130 });
    131