aboutsummaryrefslogtreecommitdiff
path: root/daemon/ConfigurationXML.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/ConfigurationXML.cpp')
-rw-r--r--daemon/ConfigurationXML.cpp153
1 files changed, 88 insertions, 65 deletions
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index 14c2809..9d51f26 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2012. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2013. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -10,30 +10,31 @@
#include <stdlib.h>
#include <dirent.h>
#include "ConfigurationXML.h"
+#include "Driver.h"
#include "Logging.h"
#include "OlyUtility.h"
#include "SessionData.h"
-static const char* ATTR_COUNTER = "counter";
-static const char* ATTR_REVISION = "revision";
-static const char* ATTR_TITLE = "title";
-static const char* ATTR_NAME = "name";
-static const char* ATTR_EVENT = "event";
-static const char* ATTR_COUNT = "count";
-static const char* ATTR_PER_CPU = "per_cpu";
-static const char* ATTR_DESCRIPTION = "description";
-static const char* ATTR_EBS = "supports_event_based_sampling";
-static const char* ATTR_DISPLAY = "display";
-static const char* ATTR_UNITS = "units";
-static const char* ATTR_AVERAGE_SELECTION = "average_selection";
+static const char* ATTR_COUNTER = "counter";
+static const char* ATTR_REVISION = "revision";
+static const char* ATTR_TITLE = "title";
+static const char* ATTR_NAME = "name";
+static const char* ATTR_EVENT = "event";
+static const char* ATTR_COUNT = "count";
+static const char* ATTR_PER_CPU = "per_cpu";
+static const char* ATTR_DESCRIPTION = "description";
+static const char* ATTR_EBS = "supports_event_based_sampling";
+static const char* ATTR_DISPLAY = "display";
+static const char* ATTR_UNITS = "units";
+static const char* ATTR_MODIFIER = "modifier";
+static const char* ATTR_AVERAGE_SELECTION = "average_selection";
ConfigurationXML::ConfigurationXML() {
const char * configuration_xml;
unsigned int configuration_xml_len;
getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
- mIndex = 0;
- char* path = (char*)malloc(PATH_MAX);
+ char path[PATH_MAX];
if (gSessionData->mConfigurationXMLPath) {
strncpy(path, gSessionData->mConfigurationXMLPath, PATH_MAX);
@@ -45,35 +46,34 @@ ConfigurationXML::ConfigurationXML() {
}
mConfigurationXML = util->readFromDisk(path);
- if (mConfigurationXML == NULL) {
- logg->logMessage("Unable to locate configuration.xml, using default in binary");
- // null-terminate configuration_xml
- mConfigurationXML = (char*)malloc(configuration_xml_len + 1);
- memcpy(mConfigurationXML, (const void*)configuration_xml, configuration_xml_len);
- mConfigurationXML[configuration_xml_len] = 0;
- }
-
- // disable all counters prior to parsing the configuration xml
- for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) {
- gSessionData->mPerfCounterEnabled[i] = 0;
- }
+ for (int retryCount = 0; retryCount < 2; ++retryCount) {
+ if (mConfigurationXML == NULL) {
+ logg->logMessage("Unable to locate configuration.xml, using default in binary");
+ // null-terminate configuration_xml
+ mConfigurationXML = (char*)malloc(configuration_xml_len + 1);
+ memcpy(mConfigurationXML, (const void*)configuration_xml, configuration_xml_len);
+ mConfigurationXML[configuration_xml_len] = 0;
+ }
- // clear counter overflow
- gSessionData->mCounterOverflow = false;
+ int ret = parse(mConfigurationXML);
+ if (ret == 1) {
+ // remove configuration.xml on disk to use the default
+ if (remove(path) != 0) {
+ logg->logError(__FILE__, __LINE__, "Invalid configuration.xml file detected and unable to delete it. To resolve, delete configuration.xml on disk");
+ handleException();
+ }
+ logg->logMessage("Invalid configuration.xml file detected and removed");
- int ret = parse(mConfigurationXML);
- if (ret == 1) {
- // remove configuration.xml on disk to use the default
- if (remove(path) != 0) {
- logg->logError(__FILE__, __LINE__, "Invalid configuration.xml file detected and unable to delete it. To resolve, delete configuration.xml on disk");
- handleException();
+ // Free the current configuration and reload
+ free((void*)mConfigurationXML);
+ mConfigurationXML = NULL;
+ continue;
}
- logg->logMessage("Invalid configuration.xml file detected and removed");
+
+ break;
}
validate();
-
- free(path);
}
ConfigurationXML::~ConfigurationXML() {
@@ -86,6 +86,15 @@ int ConfigurationXML::parse(const char* configurationXML) {
mxml_node_t *tree, *node;
int ret;
+ // clear counter overflow
+ gSessionData->mCounterOverflow = false;
+ mIndex = 0;
+
+ // disable all counters prior to parsing the configuration xml
+ for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) {
+ gSessionData->mCounters[i].setEnabled(false);
+ }
+
tree = mxmlLoadString(NULL, configurationXML, MXML_NO_CALLBACK);
node = mxmlGetFirstChild(tree);
@@ -111,18 +120,20 @@ int ConfigurationXML::parse(const char* configurationXML) {
void ConfigurationXML::validate(void) {
for (int i = 0; i < MAX_PERFORMANCE_COUNTERS; i++) {
- if (gSessionData->mPerfCounterEnabled[i]) {
- if (strcmp(gSessionData->mPerfCounterType[i], "") == 0) {
- logg->logError(__FILE__, __LINE__, "Invalid required attribute in configuration.xml:\n counter=\"%s\"\n title=\"%s\"\n name=\"%s\"\n event=%d\n", gSessionData->mPerfCounterType[i], gSessionData->mPerfCounterTitle[i], gSessionData->mPerfCounterName[i], gSessionData->mPerfCounterEvent[i]);
+ const Counter & counter = gSessionData->mCounters[i];
+ if (counter.isEnabled()) {
+ if (strcmp(counter.getType(), "") == 0) {
+ logg->logError(__FILE__, __LINE__, "Invalid required attribute in configuration.xml:\n counter=\"%s\"\n title=\"%s\"\n name=\"%s\"\n event=%d\n", counter.getType(), counter.getTitle(), counter.getName(), counter.getEvent());
handleException();
}
// iterate through the remaining enabled performance counters
for (int j = i + 1; j < MAX_PERFORMANCE_COUNTERS; j++) {
- if (gSessionData->mPerfCounterEnabled[j]) {
+ const Counter & counter2 = gSessionData->mCounters[j];
+ if (counter2.isEnabled()) {
// check if the types are the same
- if (strcmp(gSessionData->mPerfCounterType[i], gSessionData->mPerfCounterType[j]) == 0) {
- logg->logError(__FILE__, __LINE__, "Duplicate performance counter type in configuration.xml: %s", gSessionData->mPerfCounterType[i]);
+ if (strcmp(counter.getType(), counter2.getType()) == 0) {
+ logg->logError(__FILE__, __LINE__, "Duplicate performance counter type in configuration.xml: %s", counter.getType());
handleException();
}
}
@@ -131,7 +142,7 @@ void ConfigurationXML::validate(void) {
}
}
-#define CONFIGURATION_REVISION 1
+#define CONFIGURATION_REVISION 2
int ConfigurationXML::configurationsTag(mxml_node_t *node) {
const char* revision_string;
@@ -156,26 +167,38 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
}
// read attributes
- if (mxmlElementGetAttr(node, ATTR_COUNTER)) strncpy(gSessionData->mPerfCounterType[mIndex], mxmlElementGetAttr(node, ATTR_COUNTER), sizeof(gSessionData->mPerfCounterType[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_TITLE)) strncpy(gSessionData->mPerfCounterTitle[mIndex], mxmlElementGetAttr(node, ATTR_TITLE), sizeof(gSessionData->mPerfCounterTitle[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_NAME)) strncpy(gSessionData->mPerfCounterName[mIndex], mxmlElementGetAttr(node, ATTR_NAME), sizeof(gSessionData->mPerfCounterName[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) strncpy(gSessionData->mPerfCounterDescription[mIndex], mxmlElementGetAttr(node, ATTR_DESCRIPTION), sizeof(gSessionData->mPerfCounterDescription[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_EVENT)) gSessionData->mPerfCounterEvent[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16);
- if (mxmlElementGetAttr(node, ATTR_COUNT)) gSessionData->mPerfCounterCount[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10);
- if (mxmlElementGetAttr(node, ATTR_PER_CPU)) gSessionData->mPerfCounterPerCPU[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false);
- if (mxmlElementGetAttr(node, ATTR_EBS)) gSessionData->mPerfCounterEBSCapable[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false);
- if (mxmlElementGetAttr(node, ATTR_DISPLAY)) strncpy(gSessionData->mPerfCounterDisplay[mIndex], mxmlElementGetAttr(node, ATTR_DISPLAY), sizeof(gSessionData->mPerfCounterDisplay[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_UNITS)) strncpy(gSessionData->mPerfCounterUnits[mIndex], mxmlElementGetAttr(node, ATTR_UNITS), sizeof(gSessionData->mPerfCounterUnits[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false);
- gSessionData->mPerfCounterEnabled[mIndex] = true;
-
- // strncpy does not guarantee a null-terminated string
- gSessionData->mPerfCounterType[mIndex][sizeof(gSessionData->mPerfCounterType[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterDescription[mIndex][sizeof(gSessionData->mPerfCounterDescription[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0;
+ Counter & counter = gSessionData->mCounters[mIndex];
+ counter.clear();
+ if (mxmlElementGetAttr(node, ATTR_COUNTER)) counter.setType(mxmlElementGetAttr(node, ATTR_COUNTER));
+ if (mxmlElementGetAttr(node, ATTR_TITLE)) counter.setTitle(mxmlElementGetAttr(node, ATTR_TITLE));
+ if (mxmlElementGetAttr(node, ATTR_NAME)) counter.setName(mxmlElementGetAttr(node, ATTR_NAME));
+ if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) counter.setDescription(mxmlElementGetAttr(node, ATTR_DESCRIPTION));
+ if (mxmlElementGetAttr(node, ATTR_EVENT)) counter.setEvent(strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16));
+ if (mxmlElementGetAttr(node, ATTR_COUNT)) counter.setCount(strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10));
+ if (mxmlElementGetAttr(node, ATTR_PER_CPU)) counter.setPerCPU(util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false));
+ if (mxmlElementGetAttr(node, ATTR_EBS)) counter.setEBSCapable(util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false));
+ if (mxmlElementGetAttr(node, ATTR_DISPLAY)) counter.setDisplay(mxmlElementGetAttr(node, ATTR_DISPLAY));
+ if (mxmlElementGetAttr(node, ATTR_UNITS)) counter.setUnits(mxmlElementGetAttr(node, ATTR_UNITS));
+ if (mxmlElementGetAttr(node, ATTR_MODIFIER)) counter.setModifier(strtol(mxmlElementGetAttr(node, ATTR_MODIFIER), NULL, 10));
+ if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) counter.setAverageSelection(util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false));
+ counter.setEnabled(true);
+
+ // Associate a driver with each counter
+ for (Driver *driver = Driver::getHead(); driver != NULL; driver = driver->getNext()) {
+ if (driver->claimCounter(counter)) {
+ if (counter.getDriver() != NULL) {
+ logg->logError(__FILE__, __LINE__, "More than one driver has claimed %s: %s", counter.getTitle(), counter.getName());
+ handleException();
+ }
+ counter.setDriver(driver);
+ }
+ }
+
+ // If no driver is associated with the counter, disable it
+ if (counter.getDriver() == NULL) {
+ logg->logMessage("No driver has claimed %s (%s: %s)", counter.getType(), counter.getTitle(), counter.getName());
+ counter.setEnabled(false);
+ }
// update counter index
mIndex++;