// 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
};
});