aboutsummaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2012-10-13 12:00:00 -0700
committerDrew Richardson <drew.richardson@arm.com>2014-12-19 15:31:23 -0800
commitb04e8aefeed42f23955e88c7aa1611e49bdf5909 (patch)
treeeeee0f97880889c93457dfe96bdc96e487864506 /daemon
parent5f9955b9c65967a7a62f7860295d8ac187c9ec11 (diff)
gator: Version 5.125.12
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
Diffstat (limited to 'daemon')
-rw-r--r--daemon/CapturedXML.cpp26
-rw-r--r--daemon/CapturedXML.h4
-rw-r--r--daemon/Child.cpp7
-rw-r--r--daemon/Collector.cpp5
-rw-r--r--daemon/ConfigurationXML.cpp32
-rw-r--r--daemon/ConfigurationXML.h3
-rw-r--r--daemon/LocalCapture.cpp96
-rw-r--r--daemon/LocalCapture.h5
-rw-r--r--daemon/Makefile11
-rw-r--r--daemon/OlyUtility.cpp4
-rw-r--r--daemon/Sender.cpp5
-rw-r--r--daemon/Sender.h1
-rw-r--r--daemon/SessionData.cpp21
-rw-r--r--daemon/SessionData.h8
-rw-r--r--daemon/SessionXML.cpp35
-rw-r--r--daemon/SessionXML.h4
-rw-r--r--daemon/StreamlineSetup.cpp69
-rw-r--r--daemon/StreamlineSetup.h1
-rw-r--r--daemon/configuration.xml70
-rw-r--r--daemon/events-ARM11.xml8
-rw-r--r--daemon/events-ARM11MPCore.xml8
-rw-r--r--daemon/events-Cortex-A15.xml12
-rw-r--r--daemon/events-Cortex-A5.xml7
-rw-r--r--daemon/events-Cortex-A7.xml9
-rw-r--r--daemon/events-Cortex-A8.xml9
-rw-r--r--daemon/events-Cortex-A9.xml11
-rw-r--r--daemon/events-Krait-architected.xml9
-rw-r--r--daemon/events-L2C-310.xml7
-rw-r--r--daemon/events-Linux.xml6
-rw-r--r--daemon/events-Mali-400.xml53
-rw-r--r--daemon/events-Scorpion.xml9
-rw-r--r--daemon/events-ScorpionMP.xml9
-rw-r--r--daemon/main.cpp55
33 files changed, 224 insertions, 395 deletions
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index f02ed2a..30d984f 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -22,12 +22,12 @@ CapturedXML::CapturedXML() {
CapturedXML::~CapturedXML() {
}
-mxml_node_t* CapturedXML::getTree() {
+mxml_node_t* CapturedXML::getTree(bool includeTime) {
bool perfCounters = false;
mxml_node_t *xml;
- mxml_node_t *captured;
- mxml_node_t *target;
- mxml_node_t *counters;
+ mxml_node_t *captured;
+ mxml_node_t *target;
+ mxml_node_t *counters;
mxml_node_t *counter;
int x;
@@ -43,11 +43,10 @@ mxml_node_t* CapturedXML::getTree() {
captured = mxmlNewElement(xml, "captured");
mxmlElementSetAttr(captured, "version", "1");
mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
- if (gSessionData->mBytes > 0) { // Send the following only after the capture is complete
+ if (includeTime) { // Send the following only after the capture is complete
if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010)
mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038
}
- mxmlElementSetAttrf(captured, "bytes", "%d", gSessionData->mBytes);
}
target = mxmlNewElement(captured, "target");
@@ -69,18 +68,9 @@ mxml_node_t* CapturedXML::getTree() {
if (gSessionData->mPerfCounterPerCPU[x]) {
mxmlElementSetAttr(counter, "per_cpu", "yes");
}
- if (strlen(gSessionData->mPerfCounterOperation[x]) > 0) {
- mxmlElementSetAttr(counter, "operation", gSessionData->mPerfCounterOperation[x]);
- }
if (gSessionData->mPerfCounterCount[x] > 0) {
mxmlElementSetAttrf(counter, "count", "%d", gSessionData->mPerfCounterCount[x]);
}
- if (gSessionData->mPerfCounterLevel[x]) {
- mxmlElementSetAttr(counter, "level", "yes");
- }
- if (strlen(gSessionData->mPerfCounterAlias[x]) > 0) {
- mxmlElementSetAttr(counter, "alias", gSessionData->mPerfCounterAlias[x]);
- }
if (strlen(gSessionData->mPerfCounterDisplay[x]) > 0) {
mxmlElementSetAttr(counter, "display", gSessionData->mPerfCounterDisplay[x]);
}
@@ -98,9 +88,9 @@ mxml_node_t* CapturedXML::getTree() {
return xml;
}
-char* CapturedXML::getXML() {
+char* CapturedXML::getXML(bool includeTime) {
char* xml_string;
- mxml_node_t *xml = getTree();
+ mxml_node_t *xml = getTree(includeTime);
xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
mxmlDelete(xml);
return xml_string;
@@ -112,7 +102,7 @@ void CapturedXML::write(char* path) {
// Set full path
snprintf(file, PATH_MAX, "%s/captured.xml", path);
- char* xml = getXML();
+ char* xml = getXML(true);
if (util->writeToDisk(file, xml) < 0) {
logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
handleException();
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index 984d1f2..3f6a4de 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -16,10 +16,10 @@ class CapturedXML {
public:
CapturedXML();
~CapturedXML();
- char* getXML(); // the string should be freed by the caller
+ char* getXML(bool includeTime); // the string should be freed by the caller
void write(char* path);
private:
- mxml_node_t* getTree();
+ mxml_node_t* getTree(bool includeTime);
};
#endif //__CAPTURED_XML_H__
diff --git a/daemon/Child.cpp b/daemon/Child.cpp
index 2c7c292..b97e0db 100644
--- a/daemon/Child.cpp
+++ b/daemon/Child.cpp
@@ -102,7 +102,10 @@ void* stopThread(void* pVoid) {
prctl(PR_SET_NAME, (unsigned long)&"gatord-stopper", 0, 0, 0);
while (gSessionData->mSessionIsActive) {
// This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected
- if (socket->receiveNBytes(&type, sizeof(type)) > 0) {
+ const int result = socket->receiveNBytes(&type, sizeof(type));
+ if (result == -1) {
+ child->endSession();
+ } else if (result > 0) {
if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) {
logg->logMessage("INVESTIGATE: Received unknown command type %d", type);
} else {
@@ -228,7 +231,7 @@ void Child::run() {
}
gSessionData->parseSessionXML(xmlString);
localCapture = new LocalCapture();
- localCapture->createAPCDirectory(gSessionData->mTargetPath, gSessionData->mTitle);
+ localCapture->createAPCDirectory(gSessionData->mTargetPath);
localCapture->copyImages(gSessionData->mImages);
localCapture->write(xmlString);
sender->createDataFile(gSessionData->mAPCDir);
diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp
index d29cd16..25bb934 100644
--- a/daemon/Collector.cpp
+++ b/daemon/Collector.cpp
@@ -202,7 +202,10 @@ void Collector::stop() {
int Collector::collect(char* buffer) {
// Calls event_buffer_read in the driver
- int bytesRead = read(mBufferFD, buffer, mBufferSize);
+ int bytesRead;
+
+ errno = 0;
+ bytesRead = read(mBufferFD, buffer, mBufferSize);
// If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data
if (bytesRead == -1 && errno == EINTR) {
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index 145ddbd..df83697 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -21,20 +21,19 @@ 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_COLOR = "color";
static const char* ATTR_COUNT = "count";
-static const char* ATTR_OPERATION = "operation";
static const char* ATTR_PER_CPU = "per_cpu";
static const char* ATTR_DESCRIPTION = "description";
-static const char* ATTR_EBS = "event_based_sampling";
-static const char* ATTR_LEVEL = "level";
-static const char* ATTR_ALIAS = "alias";
+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";
ConfigurationXML::ConfigurationXML() {
-#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
+ const char * configuration_xml;
+ unsigned int configuration_xml_len;
+ getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
+
mIndex = 0;
char* path = (char*)malloc(PATH_MAX);
@@ -61,6 +60,9 @@ ConfigurationXML::ConfigurationXML() {
gSessionData->mPerfCounterEnabled[i] = 0;
}
+ // clear counter overflow
+ gSessionData->mCounterOverflow = false;
+
int ret = parse(mConfigurationXML);
if (ret == 1) {
// remove configuration.xml on disk to use the default
@@ -151,8 +153,8 @@ int ConfigurationXML::configurationsTag(mxml_node_t *node) {
void ConfigurationXML::configurationTag(mxml_node_t *node) {
// handle all other performance counters
if (mIndex >= MAX_PERFORMANCE_COUNTERS) {
- logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS);
- handleException();
+ gSessionData->mCounterOverflow = true;
+ return;
}
// read attributes
@@ -162,12 +164,8 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
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_COLOR)) gSessionData->mPerfCounterColor[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COLOR), NULL, 16);
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_OPERATION)) strncpy(gSessionData->mPerfCounterOperation[mIndex], mxmlElementGetAttr(node, ATTR_OPERATION), sizeof(gSessionData->mPerfCounterOperation[mIndex]));
- if (mxmlElementGetAttr(node, ATTR_LEVEL)) gSessionData->mPerfCounterLevel[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_LEVEL), false);
- if (mxmlElementGetAttr(node, ATTR_ALIAS)) strncpy(gSessionData->mPerfCounterAlias[mIndex], mxmlElementGetAttr(node, ATTR_ALIAS), sizeof(gSessionData->mPerfCounterAlias[mIndex]));
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);
@@ -178,11 +176,17 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
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->mPerfCounterOperation[mIndex][sizeof(gSessionData->mPerfCounterOperation[mIndex]) - 1] = 0;
- gSessionData->mPerfCounterAlias[mIndex][sizeof(gSessionData->mPerfCounterAlias[mIndex]) - 1] = 0;
gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0;
gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0;
// update counter index
mIndex++;
}
+
+void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) {
+ // the first line of configuration_xml.h is "unsigned char configuration_xml", but configuration_xml needs to be const static as well
+ const static
+#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
+ xml = (const char *)configuration_xml;
+ len = configuration_xml_len;
+}
diff --git a/daemon/ConfigurationXML.h b/daemon/ConfigurationXML.h
index b48d32f..66ad587 100644
--- a/daemon/ConfigurationXML.h
+++ b/daemon/ConfigurationXML.h
@@ -13,10 +13,13 @@
class ConfigurationXML {
public:
+ static void getDefaultConfigurationXml(const char * & xml, unsigned int & len);
+
ConfigurationXML();
~ConfigurationXML();
const char* getConfigurationXML() {return mConfigurationXML;}
void validate(void);
+
private:
char* mConfigurationXML;
int mIndex;
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp
index 6449d03..f8cd17f 100644
--- a/daemon/LocalCapture.cpp
+++ b/daemon/LocalCapture.cpp
@@ -23,8 +23,8 @@ LocalCapture::LocalCapture() {}
LocalCapture::~LocalCapture() {}
-void LocalCapture::createAPCDirectory(char* target_path, char* name) {
- gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc", name);
+void LocalCapture::createAPCDirectory(char* target_path) {
+ gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc");
if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) {
logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir);
handleException();
@@ -46,17 +46,14 @@ void LocalCapture::write(char* string) {
free(file);
}
-char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending, char* title) {
- int i;
+char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending) {
char* output;
char* path = (char*)malloc(PATH_MAX);
// Ensure the path is an absolute path, i.e. starts with a slash
if (initialPath == 0 || strlen(initialPath) == 0) {
- if (getcwd(path, PATH_MAX) == 0) {
- logg->logMessage("Unable to retrive the current working directory");
- }
- strncat(path, "/@F_@N", PATH_MAX - strlen(path) - 1);
+ logg->logError(__FILE__, __LINE__, "Missing -o command line option required for a local capture.");
+ handleException();
} else if (initialPath[0] != '/') {
if (getcwd(path, PATH_MAX) == 0) {
logg->logMessage("Unable to retrive the current working directory");
@@ -68,98 +65,17 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e
path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string
}
- // Convert to uppercase
- replaceAll(path, "@f", "@F", PATH_MAX);
- replaceAll(path, "@n", "@N", PATH_MAX);
-
- // Replace @F with the session xml title
- replaceAll(path, "@F", title, PATH_MAX);
-
// Add ending if it is not already there
if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) {
strncat(path, ending, PATH_MAX - strlen(path) - 1);
}
- // Replace @N with a unique integer
- if (strstr(path, "@N")) {
- char* tempPath = (char*)malloc(PATH_MAX);
- for (i = 1; i < 1000; i++) {
- char number[4];
- snprintf(number, sizeof(number), "%03d", i);
- strcpy(tempPath, path);
- replaceAll(tempPath, "@N", number, PATH_MAX);
- struct stat mFileInfo;
- if (stat(tempPath, &mFileInfo) != 0) {
- // if the direcotry does not exist, break
- break;
- }
- }
-
- if (i == 1000) {
- logg->logError(__FILE__, __LINE__, "Unable to create .apc directory, please delete older directories.");
- handleException();
- }
-
- output = strdup(tempPath);
- free(tempPath);
- } else {
- output = strdup(path);
- }
+ output = strdup(path);
free(path);
return output;
}
-//Replaces all occurrences of <find> in <target> with <replace> provided enough <size> is available
-void LocalCapture::replaceAll(char* target, const char* find, const char* replace, unsigned int size) {
- char* nextOccurrence;
- unsigned int count = 0;
-
- // Duplicate the original string
- char* original = strdup(target);
- char* ptr = original;
-
- // Determine number of <find>s
- ptr = strstr(ptr, find);
- while (ptr) {
- count++;
- ptr += strlen(find);
- ptr = strstr(ptr, find);
- }
-
- // Is there enough space available
- if (strlen(target) + (strlen(replace) - strlen(find)) * count > size - 1) {
- free(original);
- return;
- }
-
- // Reset
- ptr = original;
-
- nextOccurrence = strstr(ptr, find);
- while (nextOccurrence) {
- // Move pointers to location of replace
- int length = nextOccurrence - ptr;
- target += length;
- ptr += length;
-
- // Replace <find> with <replace>
- memcpy(target, replace, strlen(replace));
-
- // Increment over <replace>/<find>
- target += strlen(replace);
- ptr += strlen(find);
-
- // Copy remainder of ptr
- strcpy(target, ptr);
-
- // Get next occurrence
- nextOccurrence = strstr(ptr, find);
- }
-
- free(original);
-}
-
int LocalCapture::removeDirAndAllContents(char* path) {
int error = 0;
struct stat mFileInfo;
diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h
index ca37f6e..40f7883 100644
--- a/daemon/LocalCapture.h
+++ b/daemon/LocalCapture.h
@@ -17,10 +17,9 @@ public:
~LocalCapture();
void write(char* string);
void copyImages(ImageLinkList* ptr);
- void createAPCDirectory(char* target_path, char* name);
+ void createAPCDirectory(char* target_path);
private:
- char* createUniqueDirectory(const char* path, const char* ending, char* title);
- void replaceAll(char* target, const char* find, const char* replace, unsigned int size);
+ char* createUniqueDirectory(const char* path, const char* ending);
int removeDirAndAllContents(char* path);
};
diff --git a/daemon/Makefile b/daemon/Makefile
index b62a223..5562db7 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -3,7 +3,11 @@
#
# Uncomment and define CROSS_COMPILE if it is not already defined
-# CROSS_COMPILE=/path/to/cross-compiler/arm-none-linux-gnueabi-
+# CROSS_COMPILE=/path/to/cross-compiler/arm-linux-gnueabihf-
+# NOTE: This toolchain uses the hardfloat abi by default. For non-hardfloat
+# targets it is necessary to add options
+# '-marm -march=armv4t -mfloat-abi=soft'.
+
ARCH=arm
CPP=$(CROSS_COMPILE)g++
@@ -17,7 +21,10 @@ GCC=$(CROSS_COMPILE)gcc
# -std=c++0x is the planned new c++ standard
# -std=c++98 is the 1998 c++ standard
# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc
-CFLAGS=-O3 -Wall -Werror -Wno-error=sequence-point -mthumb-interwork
+CFLAGS=-O3 -Wall -mthumb-interwork
+ifeq ($(WERROR),1)
+ CFLAGS += -Werror
+endif
# -s strips the binary of debug info
LDFLAGS=-s
TARGET=gatord
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp
index c72b0d1..adc7aba 100644
--- a/daemon/OlyUtility.cpp
+++ b/daemon/OlyUtility.cpp
@@ -24,6 +24,10 @@ OlyUtility* util = NULL;
bool OlyUtility::stringToBool(const char* string, bool defValue) {
char value[32];
+ if (string == NULL) {
+ return defValue;
+ }
+
strncpy(value, string, sizeof(value));
if (value[0] == 0) {
return defValue;
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp
index efff753..eba8343 100644
--- a/daemon/Sender.cpp
+++ b/daemon/Sender.cpp
@@ -38,8 +38,9 @@ Sender::Sender(OlySocket* socket) {
}
// Send magic sequence - must be done first, afterwhich error messages can be sent
- char magic[] = {'G', 'A', 'T', 'O', 'R', '\n'};
- mDataSocket->send(magic, sizeof(magic));
+ char magic[32];
+ snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION);
+ mDataSocket->send(magic, strlen(magic));
gSessionData->mWaitingOnCommand = true;
logg->logMessage("Completed magic sequence");
diff --git a/daemon/Sender.h b/daemon/Sender.h
index 98467e0..ceab343 100644
--- a/daemon/Sender.h
+++ b/daemon/Sender.h
@@ -14,7 +14,6 @@
#include "OlySocket.h"
enum {
- RESPONSE_END = 0, // unused
RESPONSE_XML = 1,
RESPONSE_APC_DATA = 3,
RESPONSE_ACK = 4,
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index a245369..5aa3f11 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -30,10 +30,10 @@ void SessionData::initialize() {
mConfigurationXMLPath = NULL;
mSessionXMLPath = NULL;
mEventsXMLPath = NULL;
+ mTargetPath = NULL;
mAPCDir = NULL;
mSampleRate = 0;
mDuration = 0;
- mBytes = 0;
mBacktraceDepth = 0;
mTotalBufferSize = 0;
mCores = 1;
@@ -48,8 +48,6 @@ void SessionData::initializeCounters() {
mPerfCounterTitle[i][0] = 0;
mPerfCounterName[i][0] = 0;
mPerfCounterDescription[i][0] = 0;
- mPerfCounterOperation[i][0] = 0;
- mPerfCounterAlias[i][0] = 0;
mPerfCounterDisplay[i][0] = 0;
mPerfCounterUnits[i][0] = 0;
mPerfCounterEnabled[i] = 0;
@@ -59,7 +57,6 @@ void SessionData::initializeCounters() {
mPerfCounterCount[i] = 0;
mPerfCounterPerCPU[i] = false;
mPerfCounterEBSCapable[i] = false;
- mPerfCounterLevel[i] = false;
mPerfCounterAverageSelection[i] = false;
}
}
@@ -68,15 +65,6 @@ void SessionData::parseSessionXML(char* xmlString) {
SessionXML session(xmlString);
session.parse();
- // Parameter error checking
- if (session.parameters.output_path == 0 && session.parameters.target_path == 0) {
- logg->logError(__FILE__, __LINE__, "No capture path (target or host) was provided.");
- handleException();
- } else if (gSessionData->mLocalCapture && session.parameters.target_path == 0) {
- logg->logError(__FILE__, __LINE__, "Missing target_path tag in session xml required for a local capture.");
- handleException();
- }
-
// Set session data values
if (strcmp(session.parameters.sample_rate, "high") == 0) {
gSessionData->mSampleRate = 10000;
@@ -84,8 +72,11 @@ void SessionData::parseSessionXML(char* xmlString) {
gSessionData->mSampleRate = 1000;
} else if (strcmp(session.parameters.sample_rate, "low") == 0) {
gSessionData->mSampleRate = 100;
- } else {
+ } else if (strcmp(session.parameters.sample_rate, "none") == 0) {
gSessionData->mSampleRate = 0;
+ } else {
+ logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
+ handleException();
}
gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0;
gSessionData->mDuration = session.parameters.duration;
@@ -107,6 +98,4 @@ void SessionData::parseSessionXML(char* xmlString) {
}
gSessionData->mImages = session.parameters.images;
- gSessionData->mTargetPath = session.parameters.target_path;
- gSessionData->mTitle = session.parameters.title;
}
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index 6f42c07..00a71b1 100644
--- a/daemon/SessionData.h
+++ b/daemon/SessionData.h
@@ -13,7 +13,7 @@
#define MAX_STRING_LEN 80
#define MAX_DESCRIPTION_LEN 400
-#define PROTOCOL_VERSION 10
+#define PROTOCOL_VERSION 11
#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions
struct ImageLinkList {
@@ -36,7 +36,6 @@ public:
char* mEventsXMLPath;
char* mTargetPath;
char* mAPCDir;
- char* mTitle;
bool mWaitingOnCommand;
bool mSessionIsActive;
@@ -48,15 +47,13 @@ public:
int mSampleRate;
int mDuration;
int mCores;
- int mBytes;
// PMU Counters
+ bool mCounterOverflow;
char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN];
- char mPerfCounterOperation[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
- char mPerfCounterAlias[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
char mPerfCounterDisplay[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
char mPerfCounterUnits[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS];
@@ -66,7 +63,6 @@ public:
int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS];
bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS];
bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS];
- bool mPerfCounterLevel[MAX_PERFORMANCE_COUNTERS];
bool mPerfCounterAverageSelection[MAX_PERFORMANCE_COUNTERS];
};
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index f1a8258..4c373d8 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -19,21 +19,13 @@ static const char* TAG_SESSION = "session";
static const char* TAG_IMAGE = "image";
static const char* ATTR_VERSION = "version";
-static const char* ATTR_TITLE = "title";
-static const char* ATTR_UUID = "uuid";
static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding";
static const char* ATTR_BUFFER_MODE = "buffer_mode";
static const char* ATTR_SAMPLE_RATE = "sample_rate";
-static const char* ATTR_TARGET_PATH = "target_path";
-static const char* ATTR_OUTPUT_PATH = "output_path";
static const char* ATTR_DURATION = "duration";
static const char* ATTR_PATH = "path";
SessionXML::SessionXML(const char* str) {
- parameters.title = 0;
- parameters.uuid[0] = 0;
- parameters.target_path = 0;
- parameters.output_path = 0;
parameters.buffer_mode[0] = 0;
parameters.sample_rate[0] = 0;
parameters.duration = 0;
@@ -75,34 +67,7 @@ void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
handleException();
}
- // allocate strings
- if (mxmlElementGetAttr(node, ATTR_TITLE)) {
- parameters.title = strdup(mxmlElementGetAttr(node, ATTR_TITLE)); // freed when the child process exits
- if (parameters.title == NULL) {
- logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title");
- handleException();
- }
- }
- if (mxmlElementGetAttr(node, ATTR_TARGET_PATH)) {
- parameters.target_path = strdup(mxmlElementGetAttr(node, ATTR_TARGET_PATH)); // freed when the child process exits
- if (parameters.target_path == NULL) {
- logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path");
- handleException();
- }
- }
- if (mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)) {
- parameters.output_path = strdup(mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)); // freed when the child process exits
- if (parameters.output_path == NULL) {
- logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path");
- handleException();
- }
- }
-
// copy to pre-allocated strings
- if (mxmlElementGetAttr(node, ATTR_UUID)) {
- strncpy(parameters.uuid, mxmlElementGetAttr(node, ATTR_UUID), sizeof(parameters.uuid));
- parameters.uuid[sizeof(parameters.uuid) - 1] = 0; // strncpy does not guarantee a null-terminated string
- }
if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) {
strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode));
parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string
diff --git a/daemon/SessionXML.h b/daemon/SessionXML.h
index c2b5489..f7a5641 100644
--- a/daemon/SessionXML.h
+++ b/daemon/SessionXML.h
@@ -13,10 +13,6 @@
#include "SessionData.h"
struct ConfigParameters {
- char* title; // status title
- char uuid[64]; // universal unique identifier
- char* target_path; // target path of where to write to disk
- char* output_path; // host path of where to write to disk
char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size
char sample_rate[64]; // capture mode, "high", "normal", or "low"
int duration; // length of profile in seconds
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index 53729ab..3f59eab 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -28,13 +28,13 @@ static const char* TAG_SESSION = "session";
static const char* TAG_REQUEST = "request";
static const char* TAG_CONFIGURATIONS = "configurations";
-static const char* ATTR_PROTOCOL = "protocol";
-static const char* ATTR_EVENTS = "events";
-static const char* ATTR_CONFIGURATION = "configuration";
-static const char* ATTR_COUNTERS = "counters";
-static const char* ATTR_SESSION = "session";
-static const char* ATTR_CAPTURED = "captured";
-static const char* ATTR_DEFAULTS = "defaults";
+static const char* ATTR_TYPE = "type";
+static const char* VALUE_EVENTS = "events";
+static const char* VALUE_CONFIGURATION = "configuration";
+static const char* VALUE_COUNTERS = "counters";
+static const char* VALUE_SESSION = "session";
+static const char* VALUE_CAPTURED = "captured";
+static const char* VALUE_DEFAULTS = "defaults";
StreamlineSetup::StreamlineSetup(OlySocket* s) {
bool ready = false;
@@ -81,6 +81,11 @@ StreamlineSetup::StreamlineSetup(OlySocket* s) {
free(data);
}
+
+ if (gSessionData->mCounterOverflow) {
+ logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS);
+ handleException();
+ }
}
StreamlineSetup::~StreamlineSetup() {
@@ -143,30 +148,32 @@ char* StreamlineSetup::readCommand(int* command) {
void StreamlineSetup::handleRequest(char* xml) {
mxml_node_t *tree, *node;
+ const char * attr = NULL;
tree = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK);
- if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_PROTOCOL, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_PROTOCOL), false)) {
- sendProtocol();
- logg->logMessage("Sent protocol xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_EVENTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_EVENTS), false)) {
+ node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_TYPE, NULL, MXML_DESCEND_FIRST);
+ if (node) {
+ attr = mxmlElementGetAttr(node, ATTR_TYPE);
+ }
+ if (attr && strcmp(attr, VALUE_EVENTS) == 0) {
sendEvents();
logg->logMessage("Sent events xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CONFIGURATION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CONFIGURATION), false)) {
+ } else if (attr && strcmp(attr, VALUE_CONFIGURATION) == 0) {
sendConfiguration();
logg->logMessage("Sent configuration xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_COUNTERS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_COUNTERS), false)) {
+ } else if (attr && strcmp(attr, VALUE_COUNTERS) == 0) {
sendCounters();
logg->logMessage("Sent counters xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_SESSION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_SESSION), false)) {
+ } else if (attr && strcmp(attr, VALUE_SESSION) == 0) {
sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML);
logg->logMessage("Sent session xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CAPTURED, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CAPTURED), false)) {
+ } else if (attr && strcmp(attr, VALUE_CAPTURED) == 0) {
CapturedXML capturedXML;
- char* capturedText = capturedXML.getXML();
+ char* capturedText = capturedXML.getXML(false);
sendData(capturedText, strlen(capturedText), RESPONSE_XML);
free(capturedText);
logg->logMessage("Sent captured xml response");
- } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_DEFAULTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_DEFAULTS), false)) {
+ } else if (attr && strcmp(attr, VALUE_DEFAULTS) == 0) {
sendDefaults();
logg->logMessage("Sent default configuration xml response");
} else {
@@ -215,21 +222,6 @@ void StreamlineSetup::sendData(const char* data, int length, int type) {
mSocket->send((char*)data, length);
}
-void StreamlineSetup::sendProtocol() {
- mxml_node_t *xml;
- mxml_node_t *protocol;
-
- xml = mxmlNewXML("1.0");
- protocol = mxmlNewElement(xml, "protocol");
- mxmlElementSetAttrf(protocol, "version", "%d", PROTOCOL_VERSION);
-
- char* string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
- sendString(string, RESPONSE_XML);
-
- free(string);
- mxmlDelete(xml);
-}
-
void StreamlineSetup::sendEvents() {
#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
char* path = (char*)malloc(PATH_MAX);;
@@ -264,10 +256,10 @@ void StreamlineSetup::sendConfiguration() {
}
void StreamlineSetup::sendDefaults() {
-#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
// Send the config built into the binary
- char* xml = (char*)configuration_xml;
- unsigned int size = configuration_xml_len;
+ const char* xml;
+ unsigned int size;
+ ConfigurationXML::getDefaultConfigurationXml(xml, size);
// Artificial size restriction
if (size > 1024*1024) {
@@ -282,7 +274,7 @@ void StreamlineSetup::sendDefaults() {
void StreamlineSetup::sendCounters() {
struct dirent *ent;
mxml_node_t *xml;
- mxml_node_t *counters;
+ mxml_node_t *counters;
mxml_node_t *counter;
// counters.xml is simply a file listing of /dev/gator/events
@@ -328,4 +320,9 @@ void StreamlineSetup::writeConfiguration(char* xml) {
// Re-populate gSessionData with the configuration, as it has now changed
new ConfigurationXML();
free(path);
+
+ if (gSessionData->mCounterOverflow) {
+ logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS);
+ handleException();
+ }
}
diff --git a/daemon/StreamlineSetup.h b/daemon/StreamlineSetup.h
index c46ae08..8086fe2 100644
--- a/daemon/StreamlineSetup.h
+++ b/daemon/StreamlineSetup.h
@@ -35,7 +35,6 @@ private:
void handleDeliver(char* xml);
void sendData(const char* data, int length, int type);
void sendString(const char* string, int type) {sendData(string, strlen(string), type);}
- void sendProtocol();
void sendEvents();
void sendConfiguration();
void sendDefaults();
diff --git a/daemon/configuration.xml b/daemon/configuration.xml
index 4875f1f..fbdef31 100644
--- a/daemon/configuration.xml
+++ b/daemon/configuration.xml
@@ -1,49 +1,45 @@
<?xml version="1.0" encoding='UTF-8'?>
-<configurations version="1" revision="1">
+<configurations revision="1">
<configuration counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<configuration counter="ARM_ARM11_cnt0" event="0x7" title="Instruction" name="Executed" per_cpu="yes" description="Instructions executed"/>
<configuration counter="ARM_ARM11_cnt1" event="0xb" title="Cache" name="Data miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/>
<configuration counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<configuration counter="ARM_ARM11MPCore_cnt0" event="0x08" title="Core" name="Instructions" per_cpu="yes" description="Instructions executed"/>
<configuration counter="ARM_ARM11MPCore_cnt1" event="0x0b" title="Cache" name="Data read miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/>
- <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
- <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
- <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/>
- <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/>
- <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" event_based_sampling="yes" description="Any accesses to the L2 cache"/>
- <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
- <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/>
- <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
- <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" event_based_sampling="yes" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
- <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/>
- <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
- <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" event_based_sampling="yes" description=""/>
- <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
- <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
- <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
- <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/>
- <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
+ <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/>
+ <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/>
+ <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any accesses to the L2 cache"/>
+ <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/>
+ <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" supports_event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
+ <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" supports_event_based_sampling="yes" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
+ <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/>
+ <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" supports_event_based_sampling="yes" description=""/>
+ <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
+ <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
+ <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
<configuration counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/>
<configuration counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/>
- <configuration counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/>
- <configuration counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/>
- <configuration counter="Linux_cpuload_system" title="CPU Load" name="System" description="Scheduler CPU Load of System Behavior"/>
- <configuration counter="Linux_cpuload_user" title="CPU Load" name="User" description="Scheduler CPU Load of User Application"/>
<configuration counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/>
<configuration counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/>
<configuration counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/>
diff --git a/daemon/events-ARM11.xml b/daemon/events-ARM11.xml
index d4a2914..0a5ee66 100644
--- a/daemon/events-ARM11.xml
+++ b/daemon/events-ARM11.xml
@@ -1,9 +1,5 @@
- <counter_set name="ARM_ARM11_cntX">
- <counter name="ARM_ARM11_cnt0"/>
- <counter name="ARM_ARM11_cnt1"/>
- <counter name="ARM_ARM11_cnt2"/>
- </counter_set>
- <category name="ARM11" counter_set="ARM_ARM11_cntX" per_cpu="yes">
+ <counter_set name="ARM_ARM11_cnt" count="3"/>
+ <category name="ARM11" counter_set="ARM_ARM11_cnt" per_cpu="yes">
<event counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/>
<event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/>
diff --git a/daemon/events-ARM11MPCore.xml b/daemon/events-ARM11MPCore.xml
index 7de51b0..1a9ca3f 100644
--- a/daemon/events-ARM11MPCore.xml
+++ b/daemon/events-ARM11MPCore.xml
@@ -1,9 +1,5 @@
- <counter_set name="ARM_ARM11MPCore_cntX">
- <counter name="ARM_ARM11MPCore_cnt0"/>
- <counter name="ARM_ARM11MPCore_cnt1"/>
- <counter name="ARM_ARM11MPCore_cnt2"/>
- </counter_set>
- <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cntX" per_cpu="yes">
+ <counter_set name="ARM_ARM11MPCore_cnt" count="3"/>
+ <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cnt" per_cpu="yes">
<event counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/>
<event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/>
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml
index d6222eb..0ec196f 100644
--- a/daemon/events-Cortex-A15.xml
+++ b/daemon/events-Cortex-A15.xml
@@ -1,12 +1,5 @@
- <counter_set name="ARM_Cortex-A15_cntX">
- <counter name="ARM_Cortex-A15_cnt0"/>
- <counter name="ARM_Cortex-A15_cnt1"/>
- <counter name="ARM_Cortex-A15_cnt2"/>
- <counter name="ARM_Cortex-A15_cnt3"/>
- <counter name="ARM_Cortex-A15_cnt4"/>
- <counter name="ARM_Cortex-A15_cnt5"/>
- </counter_set>
- <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cntX" per_cpu="yes" event_based_sampling="yes">
+ <counter_set name="ARM_Cortex-A15_cnt" count="6"/>
+ <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
@@ -19,7 +12,6 @@
<event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
<event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
<event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
- <event event="0x11" title="Cycle" name="Cycle" description=""/>
<event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
<event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
<event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/>
diff --git a/daemon/events-Cortex-A5.xml b/daemon/events-Cortex-A5.xml
index e01492b..4a894d3 100644
--- a/daemon/events-Cortex-A5.xml
+++ b/daemon/events-Cortex-A5.xml
@@ -1,8 +1,5 @@
- <counter_set name="ARM_Cortex-A5_cntX">
- <counter name="ARM_Cortex-A5_cnt0"/>
- <counter name="ARM_Cortex-A5_cnt1"/>
- </counter_set>
- <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cntX" per_cpu="yes" event_based_sampling="yes">
+ <counter_set name="ARM_Cortex-A5_cnt" count="2"/>
+ <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml
index 9ee4580..2bd4797 100644
--- a/daemon/events-Cortex-A7.xml
+++ b/daemon/events-Cortex-A7.xml
@@ -1,10 +1,5 @@
- <counter_set name="ARM_Cortex-A7_cntX">
- <counter name="ARM_Cortex-A7_cnt0"/>
- <counter name="ARM_Cortex-A7_cnt1"/>
- <counter name="ARM_Cortex-A7_cnt2"/>
- <counter name="ARM_Cortex-A7_cnt3"/>
- </counter_set>
- <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cntX" per_cpu="yes" event_based_sampling="yes">
+ <counter_set name="ARM_Cortex-A7_cnt" count="4"/>
+ <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A8.xml b/daemon/events-Cortex-A8.xml
index 1981c36..fe4c69d 100644
--- a/daemon/events-Cortex-A8.xml
+++ b/daemon/events-Cortex-A8.xml
@@ -1,10 +1,5 @@
- <counter_set name="ARM_Cortex-A8_cntX">
- <counter name="ARM_Cortex-A8_cnt0"/>
- <counter name="ARM_Cortex-A8_cnt1"/>
- <counter name="ARM_Cortex-A8_cnt2"/>
- <counter name="ARM_Cortex-A8_cnt3"/>
- </counter_set>
- <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cntX" per_cpu="yes" event_based_sampling="yes">
+ <counter_set name="ARM_Cortex-A8_cnt" count="4"/>
+ <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml
index faccb2f..7597f78 100644
--- a/daemon/events-Cortex-A9.xml
+++ b/daemon/events-Cortex-A9.xml
@@ -1,12 +1,5 @@
- <counter_set name="ARM_Cortex-A9_cntX">
- <counter name="ARM_Cortex-A9_cnt0"/>
- <counter name="ARM_Cortex-A9_cnt1"/>
- <counter name="ARM_Cortex-A9_cnt2"/>
- <counter name="ARM_Cortex-A9_cnt3"/>
- <counter name="ARM_Cortex-A9_cnt4"/>
- <counter name="ARM_Cortex-A9_cnt5"/>
- </counter_set>
- <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cntX" per_cpu="yes" event_based_sampling="yes">
+ <counter_set name="ARM_Cortex-A9_cnt" count="6"/>
+ <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Krait-architected.xml b/daemon/events-Krait-architected.xml
index 6f2982e..06c1901 100644
--- a/daemon/events-Krait-architected.xml
+++ b/daemon/events-Krait-architected.xml
@@ -1,10 +1,5 @@
- <counter_set name="Krait_cntX">
- <counter name="Krait_cnt0"/>
- <counter name="Krait_cnt1"/>
- <counter name="Krait_cnt2"/>
- <counter name="Krait_cnt3"/>
- </counter_set>
- <category name="Krait" counter_set="Krait_cntX" per_cpu="yes">
+ <counter_set name="Krait_cnt" count="4"/>
+ <category name="Krait" counter_set="Krait_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="Krait_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-L2C-310.xml b/daemon/events-L2C-310.xml
index 695b6b8..4da4d1d 100644
--- a/daemon/events-L2C-310.xml
+++ b/daemon/events-L2C-310.xml
@@ -1,8 +1,5 @@
- <counter_set name="L2C-310_cntX">
- <counter name="L2C-310_cnt0"/>
- <counter name="L2C-310_cnt1"/>
- </counter_set>
- <category name="L2C-310" counter_set="L2C-310_cntX" per_cpu="no">
+ <counter_set name="L2C-310_cnt" count="2"/>
+ <category name="L2C-310" counter_set="L2C-310_cnt" per_cpu="no">
<event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/>
<event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/>
<event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index 3f626b3..b45a122 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -1,17 +1,15 @@
<category name="Linux">
- <event counter="Linux_cpuload_user" title="CPU Load" name="User" per_cpu="yes" description="Scheduler CPU Load of User Application"/>
- <event counter="Linux_cpuload_system" title="CPU Load" name="System" per_cpu="yes" description="Scheduler CPU Load of System Behavior"/>
<event counter="Linux_irq_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/>
<event counter="Linux_irq_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/>
<event counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/>
<event counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/>
<event counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/>
<event counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/>
- <event counter="Linux_sched_switch" title="Scheduler" name="Switch" description="Context switch events"/>
+ <event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/>
<event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/>
<event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/>
<event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by buffers"/>
<event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/>
- <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/>
+ <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State + 1, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/>
</category>
diff --git a/daemon/events-Mali-400.xml b/daemon/events-Mali-400.xml
index cb1c6b4..6830d46 100644
--- a/daemon/events-Mali-400.xml
+++ b/daemon/events-Mali-400.xml
@@ -1,33 +1,12 @@
- <counter_set name="ARM_Mali-400_VP_cntX">
- <counter name="ARM_Mali-400_VP_cnt0"/>
- <counter name="ARM_Mali-400_VP_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_FP0_cntX">
- <counter name="ARM_Mali-400_FP0_cnt0"/>
- <counter name="ARM_Mali-400_FP0_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_FP1_cntX">
- <counter name="ARM_Mali-400_FP1_cnt0"/>
- <counter name="ARM_Mali-400_FP1_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_FP2_cntX">
- <counter name="ARM_Mali-400_FP2_cnt0"/>
- <counter name="ARM_Mali-400_FP2_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_FP3_cntX">
- <counter name="ARM_Mali-400_FP3_cnt0"/>
- <counter name="ARM_Mali-400_FP3_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_L2_cntX">
- <counter name="ARM_Mali-400_L2_cnt0"/>
- <counter name="ARM_Mali-400_L2_cnt1"/>
- </counter_set>
- <counter_set name="ARM_Mali-400_SW_cntX">
- </counter_set>
- <counter_set name="ARM_Mali-400_Filmstrip_cntX">
- <counter name="ARM_Mali-400_Filmstrip"/>
- </counter_set>
- <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cntX" per_cpu="no">
+ <counter_set name="ARM_Mali-400_VP_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_FP0_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_FP1_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_FP2_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_FP3_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_L2_cnt" count="2"/>
+ <counter_set name="ARM_Mali-400_SW_cnt" count="0"/>
+ <counter_set name="ARM_Mali-400_Filmstrip_cnt" count="1"/>
+ <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cnt" per_cpu="no">
<event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/>
<event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/>
<event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/>
@@ -54,7 +33,7 @@
<event event="0x20" title="Mali GPU Vertex Processor" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoringi. This includes time spent waiting on the bus."/>
<event event="0x21" title="Mali GPU Vertex Processor" name="Active cycles, PLBU tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over the tiles in the bounding box generating commands (mainly graphics primitives). This includes time spent waiting on the bus."/>
</category>
- <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cntX" per_cpu="no">
+ <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no">
<event event="0x00" title="Mali GPU Fragment Processor 0" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
<event event="0x02" title="Mali GPU Fragment Processor 0" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
<event event="0x03" title="Mali GPU Fragment Processor 0" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -113,7 +92,7 @@
<event event="0x3c" title="Mali GPU Fragment Processor 0" name="Program cache hit count" description="Number of hits in the program cache."/>
<event event="0x3d" title="Mali GPU Fragment Processor 0" name="Program cache miss count" description="Number of misses in the program cache."/>
</category>
- <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cntX" per_cpu="no">
+ <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cnt" per_cpu="no">
<event event="0x00" title="Mali GPU Fragment Processor 1" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
<event event="0x02" title="Mali GPU Fragment Processor 1" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
<event event="0x03" title="Mali GPU Fragment Processor 1" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -172,7 +151,7 @@
<event event="0x3c" title="Mali GPU Fragment Processor 1" name="Program cache hit count" description="Number of hits in the program cache."/>
<event event="0x3d" title="Mali GPU Fragment Processor 1" name="Program cache miss count" description="Number of misses in the program cache."/>
</category>
- <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cntX" per_cpu="no">
+ <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cnt" per_cpu="no">
<event event="0x00" title="Mali GPU Fragment Processor 2" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
<event event="0x02" title="Mali GPU Fragment Processor 2" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
<event event="0x03" title="Mali GPU Fragment Processor 2" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -231,7 +210,7 @@
<event event="0x3c" title="Mali GPU Fragment Processor 2" name="Program cache hit count" description="Number of hits in the program cache."/>
<event event="0x3d" title="Mali GPU Fragment Processor 2" name="Program cache miss count" description="Number of misses in the program cache."/>
</category>
- <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cntX" per_cpu="no">
+ <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cnt" per_cpu="no">
<event event="0x00" title="Mali GPU Fragment Processor 3" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
<event event="0x02" title="Mali GPU Fragment Processor 3" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
<event event="0x03" title="Mali GPU Fragment Processor 3" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -290,7 +269,7 @@
<event event="0x3c" title="Mali GPU Fragment Processor 3" name="Program cache hit count" description="Number of hits in the program cache."/>
<event event="0x3d" title="Mali GPU Fragment Processor 3" name="Program cache miss count" description="Number of misses in the program cache."/>
</category>
- <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cntX" per_cpu="no">
+ <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cnt" per_cpu="no">
<event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles."/>
<event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles." />
<event event="0x08" title="Mali L2 Cache" name="Read transactions, master" description="Read transactions, master." />
@@ -352,7 +331,7 @@
<event event="0x67" title="Mali L2 Cache" name="Read invalidates, slave 4" description="Read invalidates, slave 4." />
<event event="0x68" title="Mali L2 Cache" name="Cacheable read transactions, slave 4" description="Cacheable read transactions, slave 4." />
</category>
- <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cntX" per_cpu="no">
+ <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cnt" per_cpu="no">
<event event="0x040a" title="ARM_Mali-400_Filmstrip" name="Freq 1:10" description="Scaled framebuffer captures every 10th frame." />
<event event="0x041e" title="ARM_Mali-400_Filmstrip" name="Freq 1:30" description="Scaled framebuffer captures every 30th frame." />
<event event="0x043c" title="ARM_Mali-400_Filmstrip" name="Freq 1:60" description="Scaled framebuffer captures every 60th frame." />
@@ -363,7 +342,7 @@
<category name="ARM_Mali-400_Frequency" per_cpu="no">
<event counter="ARM_Mali-400_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/>
</category>
- <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cntX" per_cpu="no">
+ <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no">
<!-- EGL Counters -->
<event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the the framebuffer from video memory to framebuffer."/>
<!-- glDrawElements Counters -->
diff --git a/daemon/events-Scorpion.xml b/daemon/events-Scorpion.xml
index 51ed937..1642e85 100644
--- a/daemon/events-Scorpion.xml
+++ b/daemon/events-Scorpion.xml
@@ -1,10 +1,5 @@
- <counter_set name="Scorpion_cntX">
- <counter name="Scorpion_cnt0"/>
- <counter name="Scorpion_cnt1"/>
- <counter name="Scorpion_cnt2"/>
- <counter name="Scorpion_cnt3"/>
- </counter_set>
- <category name="Scorpion" counter_set="Scorpion_cntX" per_cpu="yes">
+ <counter_set name="Scorpion_cnt" count="4"/>
+ <category name="Scorpion" counter_set="Scorpion_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="Scorpion_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-ScorpionMP.xml b/daemon/events-ScorpionMP.xml
index d3dd430..42acc64 100644
--- a/daemon/events-ScorpionMP.xml
+++ b/daemon/events-ScorpionMP.xml
@@ -1,10 +1,5 @@
- <counter_set name="ScorpionMP_cntX">
- <counter name="ScorpionMP_cnt0"/>
- <counter name="ScorpionMP_cnt1"/>
- <counter name="ScorpionMP_cnt2"/>
- <counter name="ScorpionMP_cnt3"/>
- </counter_set>
- <category name="ScorpionMP" counter_set="ScorpionMP_cntX" per_cpu="yes">
+ <counter_set name="ScorpionMP_cnt" count="4"/>
+ <category name="ScorpionMP" counter_set="ScorpionMP_cnt" per_cpu="yes" supports_event_based_sampling="yes">
<event counter="ScorpionMP_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
<event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
<event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index d972913..5bc75ef 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -17,6 +17,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <fcntl.h>
+#include <sys/mman.h>
#include "Child.h"
#include "SessionData.h"
#include "OlySocket.h"
@@ -114,6 +116,26 @@ int mountGatorFS() {
}
}
+bool init_module (const char * const location) {
+ bool ret(false);
+ const int fd = open(location, O_RDONLY);
+ if (fd >= 0) {
+ struct stat st;
+ if (fstat(fd, &st) == 0) {
+ void * const p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (p != MAP_FAILED) {
+ if (syscall(__NR_init_module, p, st.st_size, "") == 0) {
+ ret = true;
+ }
+ munmap(p, st.st_size);
+ }
+ }
+ close(fd);
+ }
+
+ return ret;
+}
+
int setupFilesystem(char* module) {
int retval;
@@ -162,11 +184,15 @@ int setupFilesystem(char* module) {
}
// Load driver
- snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location);
- if (system(command) != 0) {
- logg->logMessage("Unable to load gator.ko driver with command: %s", command);
- logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
- handleException();
+ bool success = init_module(location);
+ if (!success) {
+ logg->logMessage("init_module failed, trying insmod");
+ snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location);
+ if (system(command) != 0) {
+ logg->logMessage("Unable to load gator.ko driver with command: %s", command);
+ logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
+ handleException();
+ }
}
if (mountGatorFS() == -1) {
@@ -183,8 +209,11 @@ int shutdownFilesystem() {
umount("/dev/gator");
}
if (driverRunningAtStart == false) {
- if (system("rmmod gator >/dev/null 2>&1") != 0) {
- return -1;
+ if (syscall(__NR_delete_module, "gator", O_NONBLOCK) != 0) {
+ logg->logMessage("delete_module failed, trying rmmod");
+ if (system("rmmod gator >/dev/null 2>&1") != 0) {
+ return -1;
+ }
}
}
@@ -205,7 +234,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION);
}
- while ((c = getopt(argc, argv, "hvp:s:c:e:m:")) != -1) {
+ while ((c = getopt(argc, argv, "hvp:s:c:e:m:o:")) != -1) {
switch(c) {
case 'c':
gSessionData->mConfigurationXMLPath = optarg;
@@ -222,6 +251,9 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
case 's':
gSessionData->mSessionXMLPath = optarg;
break;
+ case 'o':
+ gSessionData->mTargetPath = optarg;
+ break;
case 'h':
case '?':
logg->logError(__FILE__, __LINE__,
@@ -232,6 +264,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
"-m module path and filename of gator.ko\n"
"-p port_number port upon which the server listens; default is 8080\n"
"-s session_xml path and filename of a session xml used for local capture\n"
+ "-o apc_dir path and name of the output for a local capture\n"
"-v version information\n"
, version_string);
handleException();
@@ -249,6 +282,11 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
handleException();
}
+ if (gSessionData->mTargetPath != NULL && gSessionData->mSessionXMLPath == NULL) {
+ logg->logError(__FILE__, __LINE__, "Missing -s command line option required for a local capture.");
+ handleException();
+ }
+
if (optind < argc) {
logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]);
handleException();
@@ -259,6 +297,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
// Gator data flow: collector -> collector fifo -> sender
int main(int argc, char** argv, char* envp[]) {
+ setsid();
gSessionData = new SessionData(); // Global data class
logg = new Logging(DEBUG); // Set up global thread-safe logging
util = new OlyUtility(); // Set up global utility class