File indexing completed on 2024-05-05 10:03:09
0001 /* 0002 This file is part of KCachegrind. 0003 0004 SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> 0005 0006 SPDX-License-Identifier: GPL-2.0-only 0007 */ 0008 0009 /* 0010 * Global configuration for KCachegrind 0011 */ 0012 0013 #include "globalconfig.h" 0014 0015 #include <QtDebug> 0016 0017 #include "config.h" 0018 #include "tracedata.h" 0019 0020 0021 // GlobalConfig defaults 0022 #define DEFAULT_SHOWPERCENTAGE true 0023 #define DEFAULT_SHOWEXPANDED false 0024 #define DEFAULT_SHOWCYCLES true 0025 #define DEFAULT_HIDETEMPLATES false 0026 #define DEFAULT_CYCLECUT 0.0 0027 #define DEFAULT_PERCENTPRECISION 2 0028 #define DEFAULT_MAXSYMBOLLENGTH 30 0029 #define DEFAULT_MAXSYMBOLCOUNT 10 0030 #define DEFAULT_MAXLISTCOUNT 100 0031 #define DEFAULT_CONTEXT 3 0032 #define DEFAULT_NOCOSTINSIDE 20 0033 0034 0035 // 0036 // GlobalConfig 0037 // 0038 0039 // Some predefined event types... 0040 QStringList GlobalConfig::knownTypes() 0041 { 0042 QStringList l; 0043 0044 l << QStringLiteral("Ir") << QStringLiteral("Dr") << QStringLiteral("Dw") 0045 << QStringLiteral("I1mr") << QStringLiteral("D1mr") << QStringLiteral("D1mw") << QStringLiteral("L1m"); 0046 // Valgrind < 3.6.0 0047 l << QStringLiteral("I2mr") << QStringLiteral("D2mr") << QStringLiteral("D2mw") << QStringLiteral("L2m"); 0048 // Valgrind 3.6.0: L2 events changed to LL (last level) events 0049 l << QStringLiteral("ILmr") << QStringLiteral("DLmr") << QStringLiteral("DLmw") << QStringLiteral("LLm"); 0050 0051 // branch simulation 0052 l << QStringLiteral("Bi") << QStringLiteral("Bim") << QStringLiteral("Bc") << QStringLiteral("Bcm") << QStringLiteral("Bm"); 0053 0054 // global bus events (e.g. CAS) 0055 l << QStringLiteral("Ge"); 0056 0057 l << QStringLiteral("Smp") << QStringLiteral("Sys") << QStringLiteral("User") << QStringLiteral("CEst"); 0058 0059 return l; 0060 } 0061 0062 0063 QString GlobalConfig::knownFormula(const QString& name) 0064 { 0065 if (name == QLatin1String("L1m")) return QStringLiteral("I1mr + D1mr + D1mw"); 0066 if (name == QLatin1String("L2m")) return QStringLiteral("I2mr + D2mr + D2mw"); 0067 if (name == QLatin1String("LLm")) return QStringLiteral("ILmr + DLmr + DLmw"); 0068 if (name == QLatin1String("Bm")) return QStringLiteral("Bim + Bcm"); 0069 if (name == QLatin1String("CEst")) 0070 return QStringLiteral("Ir + 10 Bm + 10 L1m + 20 Ge + 100 L2m + 100 LLm"); 0071 0072 return QString(); 0073 } 0074 0075 QString GlobalConfig::knownLongName(const QString& name) 0076 { 0077 if (name == QLatin1String("Ir")) return QObject::tr("Instruction Fetch"); 0078 if (name == QLatin1String("Dr")) return QObject::tr("Data Read Access"); 0079 if (name == QLatin1String("Dw")) return QObject::tr("Data Write Access"); 0080 if (name == QLatin1String("I1mr")) return QObject::tr("L1 Instr. Fetch Miss"); 0081 if (name == QLatin1String("D1mr")) return QObject::tr("L1 Data Read Miss"); 0082 if (name == QLatin1String("D1mw")) return QObject::tr("L1 Data Write Miss"); 0083 if (name == QLatin1String("I2mr")) return QObject::tr("L2 Instr. Fetch Miss"); 0084 if (name == QLatin1String("D2mr")) return QObject::tr("L2 Data Read Miss"); 0085 if (name == QLatin1String("D2mw")) return QObject::tr("L2 Data Write Miss"); 0086 if (name == QLatin1String("ILmr")) return QObject::tr("LL Instr. Fetch Miss"); 0087 if (name == QLatin1String("DLmr")) return QObject::tr("LL Data Read Miss"); 0088 if (name == QLatin1String("DLmw")) return QObject::tr("LL Data Write Miss"); 0089 if (name == QLatin1String("L1m")) return QObject::tr("L1 Miss Sum"); 0090 if (name == QLatin1String("L2m")) return QObject::tr("L2 Miss Sum"); 0091 if (name == QLatin1String("LLm")) return QObject::tr("Last-level Miss Sum"); 0092 if (name == QLatin1String("Bi")) return QObject::tr("Indirect Branch"); 0093 if (name == QLatin1String("Bim")) return QObject::tr("Mispredicted Ind. Branch"); 0094 if (name == QLatin1String("Bc")) return QObject::tr("Conditional Branch"); 0095 if (name == QLatin1String("Bcm")) return QObject::tr("Mispredicted Cond. Branch"); 0096 if (name == QLatin1String("Bm")) return QObject::tr("Mispredicted Branch"); 0097 if (name == QLatin1String("Ge")) return QObject::tr("Global Bus Event"); 0098 if (name == QLatin1String("Smp")) return QObject::tr("Samples"); 0099 if (name == QLatin1String("Sys")) return QObject::tr("System Time"); 0100 if (name == QLatin1String("User")) return QObject::tr("User Time"); 0101 if (name == QLatin1String("CEst")) return QObject::tr("Cycle Estimation"); 0102 0103 return QString(); 0104 } 0105 0106 0107 GlobalConfig* GlobalConfig::_config = nullptr; 0108 0109 GlobalConfig::GlobalConfig() 0110 { 0111 _config = nullptr; 0112 0113 // general presentation options 0114 _showPercentage = DEFAULT_SHOWPERCENTAGE; 0115 _showExpanded = DEFAULT_SHOWEXPANDED; 0116 _showCycles = DEFAULT_SHOWCYCLES; 0117 _cycleCut = DEFAULT_CYCLECUT; 0118 _percentPrecision = DEFAULT_PERCENTPRECISION; 0119 _hideTemplates = DEFAULT_HIDETEMPLATES; 0120 0121 // max symbol count/length in tooltip/popup 0122 _maxSymbolLength = DEFAULT_MAXSYMBOLLENGTH; 0123 _maxSymbolCount = DEFAULT_MAXSYMBOLCOUNT; 0124 _maxListCount = DEFAULT_MAXLISTCOUNT; 0125 0126 // annotation behaviour 0127 _context = DEFAULT_CONTEXT; 0128 _noCostInside = DEFAULT_NOCOSTINSIDE; 0129 } 0130 0131 GlobalConfig::~GlobalConfig() 0132 { 0133 } 0134 0135 GlobalConfig* GlobalConfig::config() 0136 { 0137 if (_config == nullptr) 0138 _config = new GlobalConfig(); 0139 0140 return _config; 0141 } 0142 0143 0144 void GlobalConfig::saveOptions() 0145 { 0146 // source options 0147 ConfigGroup* sourceConfig = ConfigStorage::group(QStringLiteral("Source")); 0148 sourceConfig->setValue(QStringLiteral("Dirs"), _generalSourceDirs); 0149 QHashIterator<QString,QStringList> it( _objectSourceDirs ); 0150 int count = 1; 0151 while( it.hasNext() ) { 0152 it.next(); 0153 sourceConfig->setValue( QStringLiteral("Object%1").arg(count), 0154 it.key() ); 0155 sourceConfig->setValue( QStringLiteral("Dirs%1").arg(count), 0156 it.value() ); 0157 count++; 0158 } 0159 sourceConfig->setValue(QStringLiteral("Count"), count-1); 0160 delete sourceConfig; 0161 0162 // general options 0163 ConfigGroup* generalConfig = ConfigStorage::group(QStringLiteral("GeneralSettings")); 0164 generalConfig->setValue(QStringLiteral("ShowPercentage"), _showPercentage, 0165 DEFAULT_SHOWPERCENTAGE); 0166 generalConfig->setValue(QStringLiteral("ShowExpanded"), _showExpanded, 0167 DEFAULT_SHOWEXPANDED); 0168 generalConfig->setValue(QStringLiteral("ShowCycles"), _showCycles, 0169 DEFAULT_SHOWCYCLES); 0170 generalConfig->setValue(QStringLiteral("CycleCut"), _cycleCut, 0171 DEFAULT_CYCLECUT); 0172 generalConfig->setValue(QStringLiteral("PercentPrecision"), _percentPrecision, 0173 DEFAULT_PERCENTPRECISION); 0174 generalConfig->setValue(QStringLiteral("MaxSymbolLength"), _maxSymbolLength, 0175 DEFAULT_MAXSYMBOLLENGTH); 0176 generalConfig->setValue(QStringLiteral("MaxSymbolCount"), _maxSymbolCount, 0177 DEFAULT_MAXSYMBOLCOUNT); 0178 generalConfig->setValue(QStringLiteral("MaxListCount"), _maxListCount, 0179 DEFAULT_MAXLISTCOUNT); 0180 generalConfig->setValue(QStringLiteral("Context"), _context, 0181 DEFAULT_CONTEXT); 0182 generalConfig->setValue(QStringLiteral("NoCostInside"), _noCostInside, 0183 DEFAULT_NOCOSTINSIDE); 0184 generalConfig->setValue(QStringLiteral("HideTemplates"), _hideTemplates, 0185 DEFAULT_HIDETEMPLATES); 0186 delete generalConfig; 0187 0188 // store known event types 0189 ConfigGroup* etConfig = ConfigStorage::group(QStringLiteral("EventTypes")); 0190 int etCount = EventType::knownTypeCount(); 0191 int j = 0; // counter for config keys 0192 for (int i = 0; i<etCount; i++) { 0193 EventType* t = EventType::knownType(i); 0194 // do not store derived event types with empty formula 0195 // (these can exist when new type gets added with context menu) 0196 if (!t->isReal() && t->formula().isEmpty()) continue; 0197 0198 etConfig->setValue( QStringLiteral("Name%1").arg(j+1), t->name()); 0199 etConfig->setValue( QStringLiteral("Longname%1").arg(j+1), 0200 t->longName(), 0201 knownLongName(t->name()) ); 0202 etConfig->setValue( QStringLiteral("Formula%1").arg(j+1), 0203 t->formula(), knownFormula(t->name()) ); 0204 j++; 0205 } 0206 etConfig->setValue( QStringLiteral("Count"), j); 0207 delete etConfig; 0208 } 0209 0210 void GlobalConfig::readOptions() 0211 { 0212 int i, count; 0213 0214 // source options 0215 ConfigGroup* sourceConfig = ConfigStorage::group(QStringLiteral("Source")); 0216 QStringList dirs; 0217 dirs = sourceConfig->value(QStringLiteral("Dirs"), QStringList()).toStringList(); 0218 if (dirs.count()>0) _generalSourceDirs = dirs; 0219 count = sourceConfig->value(QStringLiteral("Count"), 0).toInt(); 0220 _objectSourceDirs.clear(); 0221 for(i=1; i<=count; ++i) { 0222 QString n = sourceConfig->value(QStringLiteral("Object%1").arg(i), 0223 QString()).toString(); 0224 dirs = sourceConfig->value(QStringLiteral("Dirs%1").arg(i), 0225 QStringList()).toStringList(); 0226 0227 if (n.isEmpty() || (dirs.isEmpty())) continue; 0228 0229 _objectSourceDirs.insert(n, dirs); 0230 } 0231 delete sourceConfig; 0232 0233 // general options 0234 ConfigGroup* generalConfig = ConfigStorage::group(QStringLiteral("GeneralSettings")); 0235 _showPercentage = generalConfig->value(QStringLiteral("ShowPercentage"), 0236 DEFAULT_SHOWPERCENTAGE).toBool(); 0237 _showExpanded = generalConfig->value(QStringLiteral("ShowExpanded"), 0238 DEFAULT_SHOWEXPANDED).toBool(); 0239 _showCycles = generalConfig->value(QStringLiteral("ShowCycles"), 0240 DEFAULT_SHOWCYCLES).toBool(); 0241 _cycleCut = generalConfig->value(QStringLiteral("CycleCut"), 0242 DEFAULT_CYCLECUT).toDouble(); 0243 _percentPrecision = generalConfig->value(QStringLiteral("PercentPrecision"), 0244 DEFAULT_PERCENTPRECISION).toInt(); 0245 _maxSymbolLength = generalConfig->value(QStringLiteral("MaxSymbolLength"), 0246 DEFAULT_MAXSYMBOLLENGTH).toInt(); 0247 _maxSymbolCount = generalConfig->value(QStringLiteral("MaxSymbolCount"), 0248 DEFAULT_MAXSYMBOLCOUNT).toInt(); 0249 _maxListCount = generalConfig->value(QStringLiteral("MaxListCount"), 0250 DEFAULT_MAXLISTCOUNT).toInt(); 0251 _context = generalConfig->value(QStringLiteral("Context"), 0252 DEFAULT_CONTEXT).toInt(); 0253 _noCostInside = generalConfig->value(QStringLiteral("NoCostInside"), 0254 DEFAULT_NOCOSTINSIDE).toInt(); 0255 _hideTemplates = generalConfig->value(QStringLiteral("HideTemplates"), 0256 DEFAULT_HIDETEMPLATES).toBool(); 0257 delete generalConfig; 0258 0259 // event types 0260 if (EventType::knownTypeCount() >0) return; // already read 0261 ConfigGroup* etConfig = ConfigStorage::group(QStringLiteral("EventTypes")); 0262 int etCount = etConfig->value(QStringLiteral("Count"), 0).toInt(); 0263 0264 for (int i=1;i<=etCount;i++) { 0265 QString n = etConfig->value(QStringLiteral("Name%1").arg(i), 0266 QString()).toString(); 0267 QString l = etConfig->value(QStringLiteral("Longname%1").arg(i), 0268 QString()).toString(); 0269 if (l.isEmpty()) l = knownLongName(n); 0270 QString f = etConfig->value(QStringLiteral("Formula%1").arg(i), 0271 QString()).toString(); 0272 if (f.isEmpty()) f = knownFormula(n); 0273 0274 EventType::add(new EventType(n, l, f)); 0275 } 0276 0277 // this does only add yet non-existing types 0278 addDefaultTypes(); 0279 0280 delete etConfig; 0281 } 0282 0283 void GlobalConfig::addDefaultTypes() 0284 { 0285 QString longName, formula; 0286 EventType* ct; 0287 QStringList l = knownTypes(); 0288 for ( QStringList::const_iterator it = l.constBegin(); 0289 it != l.constEnd(); ++it ) { 0290 longName = knownLongName(*it); 0291 formula = knownFormula(*it); 0292 ct = new EventType(*it, longName, formula); 0293 EventType::add(ct, false); 0294 } 0295 } 0296 0297 /* Gives back a list of all Source Base Directories of Objects in 0298 * current trace. If a special object is given in 2nd argument, 0299 * put its Source Base in front. 0300 */ 0301 QStringList GlobalConfig::sourceDirs(TraceData* data, TraceObject* o) 0302 { 0303 QStringList l = config()->_generalSourceDirs, ol, ol2; 0304 TraceObjectMap::Iterator oit; 0305 for ( oit = data->objectMap().begin(); 0306 oit != data->objectMap().end(); ++oit ) { 0307 ol = config()->_objectSourceDirs[(*oit).name()]; 0308 if (&(*oit) == o) { 0309 ol2 = ol; 0310 continue; 0311 } 0312 0313 for(int i=0;i<ol.count();i++) 0314 l.prepend( ol[i] ); 0315 } 0316 for(int i=0;i<ol2.count();i++) 0317 l.prepend( ol2[i] ); 0318 0319 if (0) qDebug() << "GlobalConfig::sourceDirs: " << l.join(QLatin1Char(':')); 0320 0321 return l; 0322 } 0323 0324 bool GlobalConfig::showPercentage() 0325 { 0326 return config()->_showPercentage; 0327 } 0328 0329 bool GlobalConfig::showExpanded() 0330 { 0331 return config()->_showExpanded; 0332 } 0333 0334 bool GlobalConfig::showCycles() 0335 { 0336 return config()->_showCycles; 0337 } 0338 0339 bool GlobalConfig::hideTemplates() 0340 { 0341 return config()->_hideTemplates; 0342 } 0343 0344 void GlobalConfig::setShowPercentage(bool s) 0345 { 0346 GlobalConfig* c = config(); 0347 if (c->_showPercentage == s) return; 0348 0349 c->_showPercentage = s; 0350 } 0351 0352 void GlobalConfig::setShowExpanded(bool s) 0353 { 0354 GlobalConfig* c = config(); 0355 if (c->_showExpanded == s) return; 0356 0357 c->_showExpanded = s; 0358 } 0359 0360 void GlobalConfig::setShowCycles(bool s) 0361 { 0362 GlobalConfig* c = config(); 0363 if (c->_showCycles == s) return; 0364 0365 c->_showCycles = s; 0366 } 0367 0368 void GlobalConfig::setHideTemplates(bool s) 0369 { 0370 GlobalConfig* c = config(); 0371 if (c->_hideTemplates == s) return; 0372 0373 c->_hideTemplates = s; 0374 } 0375 0376 double GlobalConfig::cycleCut() 0377 { 0378 return config()->_cycleCut; 0379 } 0380 0381 int GlobalConfig::percentPrecision() 0382 { 0383 return config()->_percentPrecision; 0384 } 0385 0386 int GlobalConfig::maxSymbolLength() 0387 { 0388 return config()->_maxSymbolLength; 0389 } 0390 0391 QString GlobalConfig::shortenSymbol(const QString& s) 0392 { 0393 if(s.length() > config()->_maxSymbolLength) 0394 return s.left(config()->_maxSymbolLength) + QStringLiteral("..."); 0395 return s; 0396 } 0397 0398 int GlobalConfig::maxListCount() 0399 { 0400 return config()->_maxListCount; 0401 } 0402 0403 int GlobalConfig::maxSymbolCount() 0404 { 0405 return config()->_maxSymbolCount; 0406 } 0407 0408 int GlobalConfig::context() 0409 { 0410 return config()->_context; 0411 } 0412 0413 int GlobalConfig::noCostInside() 0414 { 0415 return config()->_noCostInside; 0416 } 0417 0418 void GlobalConfig::setPercentPrecision(int v) 0419 { 0420 if ((v<1) || (v >5)) return; 0421 _percentPrecision = v; 0422 } 0423 0424 void GlobalConfig::setMaxSymbolLength(int v) 0425 { 0426 if ((v<1) || (v >1000)) return; 0427 _maxSymbolLength = v; 0428 } 0429 0430 void GlobalConfig::setMaxSymbolCount(int v) 0431 { 0432 if ((v<1) || (v >50)) return; 0433 _maxSymbolCount = v; 0434 } 0435 0436 void GlobalConfig::setMaxListCount(int v) 0437 { 0438 if ((v<1) || (v >500)) return; 0439 _maxListCount = v; 0440 } 0441 0442 void GlobalConfig::setContext(int v) 0443 { 0444 if ((v<1) || (v >500)) return; 0445 _context = v; 0446 } 0447 0448 const QStringList& GlobalConfig::generalSourceDirs() 0449 { 0450 return _generalSourceDirs; 0451 } 0452 0453 QStringList GlobalConfig::objectSourceDirs(QString obj) 0454 { 0455 if (_objectSourceDirs.contains(obj)) 0456 return _objectSourceDirs[obj]; 0457 else 0458 return QStringList(); 0459 } 0460 0461 void GlobalConfig::setGeneralSourceDirs(QStringList dirs) 0462 { 0463 _generalSourceDirs = dirs; 0464 } 0465 0466 void GlobalConfig::setObjectSourceDirs(QString obj, QStringList dirs) 0467 { 0468 if (dirs.isEmpty()) 0469 _objectSourceDirs.remove(obj); 0470 else 0471 _objectSourceDirs.insert(obj, dirs); 0472 } 0473 0474 void GlobalConfig::clearObjectSourceDirs() 0475 { 0476 _objectSourceDirs.clear(); 0477 }