You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/tdecachegrind/tdecachegrind/configuration.cpp

503 lines
14 KiB

/* This file is part of KCachegrind.
Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
KCachegrind is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
/*
* Configuration for KCachegrind
*/
#include <tdeconfig.h>
#include <klocale.h>
#include <kdebug.h>
#include "configuration.h"
#include "tracedata.h"
#include "configdlgbase.h"
#include "traceitemview.h"
//
// Some predefined cost types...
//
static TQStringList knownTypes()
{
TQStringList l;
l << "Ir" << "Dr" << "Dw"
<< "I1mr" << "D1mr" << "D1mw"
<< "I2mr" << "D2mr" << "D2mw"
<< "Smp" << "Sys" << "User"
// Valgrind < 3.6.0
<< "L1m" << "L2m" << "CEst"
// Valgrind 3.6.0: L2 events changed to to LL (last level) events
<< "L1m" << "LLm" << "CEst";
return l;
}
static TQString knownFormula(TQString name)
{
if (name =="L1m") return TQString("I1mr + D1mr + D1mw");
if (name =="L2m") return TQString("I2mr + D2mr + D2mw");
if (name =="LLm") return TQString("I2mr + D2mr + D2mw");
if (name =="CEst") return TQString("Ir + 10 L1m + 100 L2m + 100 LLm");
return TQString();
}
static TQString knownLongName(TQString name)
{
if (name == "Ir") return i18n("Instruction Fetch");
if (name =="Dr") return i18n("Data Read Access");
if (name =="Dw") return i18n("Data Write Access");
if (name =="I1mr") return i18n("L1 Instr. Fetch Miss");
if (name =="D1mr") return i18n("L1 Data Read Miss");
if (name =="D1mw") return i18n("L1 Data Write Miss");
if (name =="I2mr") return i18n("L2 Instr. Fetch Miss");
if (name =="D2mr") return i18n("L2 Data Read Miss");
if (name =="D2mw") return i18n("L2 Data Write Miss");
if (name =="ILmr") return i18n("LL Instr. Fetch Miss");
if (name =="DLmr") return i18n("LL Data Read Miss");
if (name =="DLmw") return i18n("LL Data Write Miss");
if (name =="Smp") return i18n("Samples");
if (name =="Sys") return i18n("System Time");
if (name =="User") return i18n("User Time");
if (name =="L1m") return i18n("L1 Miss Sum");
if (name =="L2m") return i18n("L2 Miss Sum");
if (name =="LLm") return i18n("LL Miss Sum");
if (name =="CEst") return i18n("Cycle Estimation");
return TQString();
}
//
// Configuration
//
Configuration* Configuration::_config = 0;
Configuration::Configuration()
:_colors(517)
{
_config = 0;
_colors.setAutoDelete(true);
_objectSourceDirs.setAutoDelete(true);
// defaults
_showPercentage = true;
_showExpanded = false;
_showCycles = true;
_cycleCut = 0.0;
_percentPrecision = 2;
// max symbol count/length in tooltip/popup
_maxSymbolLength = 30;
_maxSymbolCount = 10;
_maxListCount = 100;
// annotation behaviour
_context = 3;
_noCostInside = 20;
}
Configuration* Configuration::config()
{
if (!_config)
_config = new Configuration();
return _config;
}
void Configuration::saveOptions(TDEConfig* tdeconfig)
{
Configuration* c = config();
// color options
TDEConfigGroup colorConfig(tdeconfig, TQCString("CostColors"));
TQDictIterator<ColorSetting> it( c->_colors );
int count = 1;
for( ; it.current(); ++it ) {
if ( !(*it)->automatic ) {
colorConfig.writeEntry( TQString("Name%1").arg(count),
it.currentKey());
colorConfig.writeEntry( TQString("Color%1").arg(count),
(*it)->color);
//tqDebug("Written Color %s (%d)", it.currentKey().ascii(), count);
count++;
}
}
colorConfig.writeEntry( "Count", count-1);
// source options
TDEConfigGroup sourceConfig(tdeconfig, TQCString("Source"));
sourceConfig.writeEntry("Dirs", c->_generalSourceDirs, ':');
TQDictIterator<TQStringList> it2( c->_objectSourceDirs );
count = 1;
for( ; it2.current(); ++it2 ) {
sourceConfig.writeEntry( TQString("Object%1").arg(count),
it2.currentKey());
sourceConfig.writeEntry( TQString("Dirs%1").arg(count),
*(*it2), ':');
count++;
}
sourceConfig.writeEntry( "Count", count-1);
// general options
TDEConfigGroup generalConfig(tdeconfig, TQCString("General"));
generalConfig.writeEntry("ShowPercentage", c->_showPercentage);
generalConfig.writeEntry("ShowExpanded", c->_showExpanded);
generalConfig.writeEntry("ShowCycles", c->_showCycles);
generalConfig.writeEntry("CycleCut", c->_cycleCut);
generalConfig.writeEntry("MaxSymbolCount", c->_maxSymbolCount);
generalConfig.writeEntry("MaxListCount", c->_maxListCount);
generalConfig.writeEntry("MaxSymbolLength", c->_maxSymbolLength);
generalConfig.writeEntry("PercentPrecision", c->_percentPrecision);
generalConfig.writeEntry("Context", c->_context);
generalConfig.writeEntry("NoCostInside", c->_noCostInside);
TDEConfigGroup ctConfig(tdeconfig, TQCString("CostTypes"));
int ctCount = TraceCostType::knownTypeCount();
ctConfig.writeEntry( "Count", ctCount);
for (int i=0; i<ctCount; i++) {
TraceCostType* t = TraceCostType::knownType(i);
ctConfig.writeEntry( TQString("Name%1").arg(i+1), t->name());
// Use localized key
TraceItemView::writeConfigEntry(&ctConfig,
TQString("Longname%1").arg(i+1).ascii(),
t->longName(),
knownLongName(t->name()).utf8().data() /*, true */ );
TraceItemView::writeConfigEntry(&ctConfig,
TQString("Formula%1").arg(i+1).ascii(),
t->formula(), knownFormula(t->name()).utf8().data());
}
}
void Configuration::readOptions(TDEConfig* tdeconfig)
{
int i, count;
Configuration* c = config();
// color options
c->_colors.clear();
// colors for default cost types:
// red for L2 or LL misses, green for L1 misses, blue for normal accesses
c->color("CostType-ILmr")->color = TQColor(240, 0, 0);
c->color("CostType-DLmr")->color = TQColor(180,40,40);
c->color("CostType-DLmw")->color = TQColor(120,80,80);
c->color("CostType-I2mr")->color = TQColor(240, 0, 0);
c->color("CostType-D2mr")->color = TQColor(180,40,40);
c->color("CostType-D2mw")->color = TQColor(120,80,80);
c->color("CostType-I1mr")->color = TQColor(0, 240, 0);
c->color("CostType-D1mr")->color = TQColor(40,180,40);
c->color("CostType-D1mw")->color = TQColor(80,120,80);
c->color("CostType-Ir")->color = TQColor(0, 0, 240);
c->color("CostType-Dr")->color = TQColor(40,40,180);
c->color("CostType-Dw")->color = TQColor(80,80,120);
TDEConfigGroup colorConfig(tdeconfig, TQCString("CostColors"));
count = colorConfig.readNumEntry("Count", 0);
for (i=1;i<=count;i++) {
TQString n = colorConfig.readEntry(TQString("Name%1").arg(i));
TQColor color = colorConfig.readColorEntry(TQString("Color%1").arg(i));
if (n.isEmpty()) continue;
ColorSetting* cs = new ColorSetting;
cs->name = n;
cs->automatic = false;
cs->color = color;
c->_colors.insert(n, cs);
//tqDebug("Read Color %s", n.ascii());
}
// source options
TDEConfigGroup sourceConfig(tdeconfig, TQCString("Source"));
TQStringList dirs;
dirs = sourceConfig.readListEntry("Dirs", ':');
if (dirs.count()>0) c->_generalSourceDirs = dirs;
count = sourceConfig.readNumEntry("Count", 0);
c->_objectSourceDirs.clear();
if (count>17) c->_objectSourceDirs.resize(count);
for (i=1;i<=count;i++) {
TQString n = sourceConfig.readEntry(TQString("Object%1").arg(i));
dirs = sourceConfig.readListEntry(TQString("Dirs%1").arg(i), ':');
if (n.isEmpty() || (dirs.count()==0)) continue;
c->_objectSourceDirs.insert(n, new TQStringList(dirs));
}
// general options
TDEConfigGroup generalConfig(tdeconfig, TQCString("General"));
c->_showPercentage = generalConfig.readBoolEntry("ShowPercentage", true);
c->_showExpanded = generalConfig.readBoolEntry("ShowExpanded", false);
c->_showCycles = generalConfig.readBoolEntry("ShowCycles", true);
c->_cycleCut = generalConfig.readDoubleNumEntry("CycleCut", 0.0);
c->_maxSymbolCount = generalConfig.readNumEntry("MaxSymbolCount", 10);
c->_maxListCount = generalConfig.readNumEntry("MaxListCount", 100);
c->_maxSymbolLength = generalConfig.readNumEntry("MaxSymbolLength", 30);
c->_percentPrecision = generalConfig.readNumEntry("PercentPrecision", 2);
c->_context = generalConfig.readNumEntry("Context", 3);
c->_noCostInside = generalConfig.readNumEntry("NoCostInside", 20);
// known cost types
if (TraceCostType::knownTypeCount()==0) {
TDEConfigGroup ctConfig(tdeconfig, TQCString("CostTypes"));
int ctCount = ctConfig.readNumEntry("Count", 0);
if (ctCount>0) {
for (int i=1;i<=ctCount;i++) {
TQString n = ctConfig.readEntry(TQString("Name%1").arg(i));
TQString l = ctConfig.readEntry(TQString("Longname%1").arg(i));
if (l.isEmpty()) l = knownLongName(n);
TQString f = ctConfig.readEntry(TQString("Formula%1").arg(i));
if (f.isEmpty()) f = knownFormula(n);
TraceCostType::add(new TraceCostType(n, l, f));
}
}
else {
// add default types
TQString longName, formula;
TraceCostType* ct;
TQStringList l = knownTypes();
for ( TQStringList::Iterator it = l.begin();
it != l.end(); ++it ) {
longName = knownLongName(*it);
formula = knownFormula(*it);
ct = new TraceCostType(*it, longName, formula);
TraceCostType::add(ct);
}
}
}
}
TQColor Configuration::groupColor(TraceItem* cost)
{
TQString n;
if (!cost)
n = TQString("default");
else
n = TraceCost::typeName(cost->type()) + "-" + cost->prettyName();
return color(n)->color;
}
TQColor Configuration::costTypeColor(TraceCostType* t)
{
TQString n;
if (!t)
n = TQString("CostType-default");
else
n = TQString("CostType-%1").arg(t->name());
return color(n)->color;
}
TQColor Configuration::functionColor(TraceCost::CostType gt,
TraceFunction* f)
{
TraceCost* group = f;
TQString n;
switch(gt) {
case TraceCost::Object: group = f->object(); break;
case TraceCost::Class: group = f->cls(); break;
case TraceCost::File: group = f->file(); break;
default:
break;
}
if (group != f) {
// first look for manual color of a function in a group
n = TraceCost::typeName(group->type()) +
"-" + group->prettyName() +
"-" + f->prettyName();
ColorSetting* cs = color(n, false);
if (cs) return cs->color;
}
return groupColor(group);
}
Configuration::ColorSetting* Configuration::color(TQString n, bool createNew)
{
// tqDebug("Color for %s", n.latin1());
// predefined ?
Configuration* c = config();
ColorSetting* cs = c->_colors[n];
if (cs || !createNew) return cs;
// automatic colors...
int h = 0, s = 100;
const char* str = n.ascii();
while (*str) {
h = (h * 37 + s* (unsigned)*str) % 256;
s = (s * 17 + h* (unsigned)*str) % 192;
str++;
}
//tqDebug("New color for %s: H %d, S %d", n.ascii(), h, 64+s);
TQColor color = TQColor(h, 64+s, 192, TQColor::Hsv);
cs = new ColorSetting;
cs->name = n;
cs->automatic = true;
cs->color = color;
c->_colors.insert(n, cs);
//tqDebug("new Color %s", n.ascii());
return cs;
}
/* Gives back a list of all Source Base Directories of Objects in
* current trace. If a special object is given in 2nd argument,
* put its Source Base in front.
*/
TQStringList Configuration::sourceDirs(TraceData* data, TraceObject* o)
{
TQStringList l = config()->_generalSourceDirs, *ol, *ol2 = 0;
TraceObjectMap::Iterator oit;
for ( oit = data->objectMap().begin();
oit != data->objectMap().end(); ++oit ) {
ol = config()->_objectSourceDirs[(*oit).name()];
if (&(*oit) == o) {
ol2 = ol;
continue;
}
if (!ol) continue;
for(unsigned int i=0;i<ol->count();i++)
l.prepend( (*ol)[i] );
}
if (ol2) {
for(unsigned int i=0;i<ol2->count();i++)
l.prepend( (*ol2)[i] );
}
if (0) kdDebug() << "Configuration::sourceDirs: " << l.join(":") << endl;
return l;
}
bool Configuration::showPercentage()
{
return config()->_showPercentage;
}
bool Configuration::showExpanded()
{
return config()->_showExpanded;
}
bool Configuration::showCycles()
{
return config()->_showCycles;
}
void Configuration::setShowPercentage(bool s)
{
Configuration* c = config();
if (c->_showPercentage == s) return;
c->_showPercentage = s;
}
void Configuration::setShowExpanded(bool s)
{
Configuration* c = config();
if (c->_showExpanded == s) return;
c->_showExpanded = s;
}
void Configuration::setShowCycles(bool s)
{
Configuration* c = config();
if (c->_showCycles == s) return;
c->_showCycles = s;
}
double Configuration::cycleCut()
{
return config()->_cycleCut;
}
int Configuration::percentPrecision()
{
return config()->_percentPrecision;
}
int Configuration::maxSymbolLength()
{
return config()->_maxSymbolLength;
}
TQString Configuration::shortenSymbol(TQString s)
{
if ((int)s.length() > maxSymbolLength())
s = s.left(maxSymbolLength()) + "...";
return s;
}
int Configuration::maxListCount()
{
return config()->_maxListCount;
}
int Configuration::maxSymbolCount()
{
return config()->_maxSymbolCount;
}
int Configuration::context()
{
return config()->_context;
}
int Configuration::noCostInside()
{
return config()->_noCostInside;
}