summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2016-04-01 12:00:00 -0700
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:49:45 +0900
commit4f9bcded03f9bab17e496a6d70045e45c5518186 (patch)
tree60f8ccd66706529077a0e86cc421342771711842 /tools
parentfbbfc4e7d8e6feb6d32bf75c4632a920356a8faf (diff)
gator: Version 5.24
Signed-off-by: Drew Richardson <drew.richardson@arm.com> [Ported from https://github.com/ARM-software/gator.git to kernel tree, out of tree files are removed] Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/gator/daemon/Android.mk1
-rw-r--r--tools/gator/daemon/AnnotateListener.cpp2
-rw-r--r--tools/gator/daemon/AnnotateListener.h2
-rw-r--r--tools/gator/daemon/AtraceDriver.cpp22
-rw-r--r--tools/gator/daemon/AtraceDriver.h2
-rw-r--r--tools/gator/daemon/Buffer.cpp2
-rw-r--r--tools/gator/daemon/Buffer.h2
-rw-r--r--tools/gator/daemon/CCNDriver.cpp2
-rw-r--r--tools/gator/daemon/CCNDriver.h2
-rw-r--r--tools/gator/daemon/CapturedXML.cpp2
-rw-r--r--tools/gator/daemon/CapturedXML.h4
-rw-r--r--tools/gator/daemon/Child.cpp2
-rw-r--r--tools/gator/daemon/Child.h2
-rw-r--r--tools/gator/daemon/Command.cpp2
-rw-r--r--tools/gator/daemon/Command.h2
-rw-r--r--tools/gator/daemon/Config.h4
-rw-r--r--tools/gator/daemon/ConfigurationXML.cpp76
-rw-r--r--tools/gator/daemon/ConfigurationXML.h4
-rw-r--r--tools/gator/daemon/Counter.h2
-rw-r--r--tools/gator/daemon/DiskIODriver.cpp2
-rw-r--r--tools/gator/daemon/DiskIODriver.h2
-rw-r--r--tools/gator/daemon/Driver.cpp2
-rw-r--r--tools/gator/daemon/Driver.h2
-rw-r--r--tools/gator/daemon/DriverSource.cpp2
-rw-r--r--tools/gator/daemon/DriverSource.h2
-rw-r--r--tools/gator/daemon/DynBuf.cpp2
-rw-r--r--tools/gator/daemon/DynBuf.h2
-rw-r--r--tools/gator/daemon/EventsXML.cpp166
-rw-r--r--tools/gator/daemon/EventsXML.h2
-rw-r--r--tools/gator/daemon/ExternalDriver.cpp2
-rw-r--r--tools/gator/daemon/ExternalDriver.h2
-rw-r--r--tools/gator/daemon/ExternalSource.cpp2
-rw-r--r--tools/gator/daemon/ExternalSource.h2
-rw-r--r--tools/gator/daemon/FSDriver.cpp2
-rw-r--r--tools/gator/daemon/FSDriver.h2
-rw-r--r--tools/gator/daemon/Fifo.cpp2
-rw-r--r--tools/gator/daemon/Fifo.h2
-rw-r--r--tools/gator/daemon/FtraceDriver.cpp8
-rw-r--r--tools/gator/daemon/FtraceDriver.h2
-rw-r--r--tools/gator/daemon/HwmonDriver.cpp4
-rw-r--r--tools/gator/daemon/HwmonDriver.h2
-rw-r--r--tools/gator/daemon/KMod.cpp2
-rw-r--r--tools/gator/daemon/KMod.h2
-rw-r--r--tools/gator/daemon/LocalCapture.cpp2
-rw-r--r--tools/gator/daemon/LocalCapture.h2
-rw-r--r--tools/gator/daemon/Logging.cpp2
-rw-r--r--tools/gator/daemon/Logging.h2
-rw-r--r--tools/gator/daemon/MaliVideoDriver.cpp21
-rw-r--r--tools/gator/daemon/MaliVideoDriver.h2
-rw-r--r--tools/gator/daemon/MemInfoDriver.cpp10
-rw-r--r--tools/gator/daemon/MemInfoDriver.h4
-rw-r--r--tools/gator/daemon/MidgardDriver.cpp4
-rw-r--r--tools/gator/daemon/MidgardDriver.h2
-rw-r--r--tools/gator/daemon/Monitor.cpp2
-rw-r--r--tools/gator/daemon/Monitor.h2
-rw-r--r--tools/gator/daemon/NetDriver.cpp2
-rw-r--r--tools/gator/daemon/NetDriver.h2
-rw-r--r--tools/gator/daemon/OlySocket.cpp2
-rw-r--r--tools/gator/daemon/OlySocket.h2
-rw-r--r--tools/gator/daemon/OlyUtility.cpp41
-rw-r--r--tools/gator/daemon/OlyUtility.h7
-rw-r--r--tools/gator/daemon/PerfBuffer.cpp2
-rw-r--r--tools/gator/daemon/PerfBuffer.h2
-rw-r--r--tools/gator/daemon/PerfDriver.cpp103
-rw-r--r--tools/gator/daemon/PerfDriver.h5
-rw-r--r--tools/gator/daemon/PerfGroup.cpp20
-rw-r--r--tools/gator/daemon/PerfGroup.h11
-rw-r--r--tools/gator/daemon/PerfSource.cpp56
-rw-r--r--tools/gator/daemon/PerfSource.h2
-rw-r--r--tools/gator/daemon/PmuXML.cpp45
-rw-r--r--tools/gator/daemon/PmuXML.h2
-rw-r--r--tools/gator/daemon/Proc.cpp18
-rw-r--r--tools/gator/daemon/Proc.h2
-rw-r--r--tools/gator/daemon/Sender.cpp2
-rw-r--r--tools/gator/daemon/Sender.h2
-rw-r--r--tools/gator/daemon/SessionData.cpp146
-rw-r--r--tools/gator/daemon/SessionData.h22
-rw-r--r--tools/gator/daemon/SessionXML.cpp17
-rw-r--r--tools/gator/daemon/SessionXML.h2
-rw-r--r--tools/gator/daemon/Source.cpp2
-rw-r--r--tools/gator/daemon/Source.h2
-rw-r--r--tools/gator/daemon/StreamlineSetup.cpp33
-rw-r--r--tools/gator/daemon/StreamlineSetup.h2
-rw-r--r--tools/gator/daemon/TtraceDriver.cpp17
-rw-r--r--tools/gator/daemon/TtraceDriver.h2
-rw-r--r--tools/gator/daemon/UEvent.cpp2
-rw-r--r--tools/gator/daemon/UEvent.h2
-rw-r--r--tools/gator/daemon/UserSpaceSource.cpp2
-rw-r--r--tools/gator/daemon/UserSpaceSource.h2
-rw-r--r--tools/gator/daemon/c++.cpp2
-rw-r--r--tools/gator/daemon/common.mk39
-rw-r--r--tools/gator/daemon/defaults.xml11
-rw-r--r--tools/gator/daemon/escape.c2
-rw-r--r--tools/gator/daemon/events-Cortex-A32.xml63
-rw-r--r--tools/gator/daemon/events-Linux.xml17
-rw-r--r--tools/gator/daemon/events-Mali-Midgard.xml8
-rw-r--r--tools/gator/daemon/main.cpp11
-rw-r--r--tools/gator/daemon/pmus.xml3
98 files changed, 787 insertions, 362 deletions
diff --git a/tools/gator/daemon/Android.mk b/tools/gator/daemon/Android.mk
index dc7b5fcbca8b..f0b3eb992a21 100644
--- a/tools/gator/daemon/Android.mk
+++ b/tools/gator/daemon/Android.mk
@@ -69,6 +69,7 @@ LOCAL_SRC_FILES := \
mxml/mxml-string.c
LOCAL_CFLAGS += -Wall -O3 -fno-exceptions -pthread -DETCDIR=\"/etc\" -Ilibsensors -fPIE
+LOCAL_CXXFLAGS += -fno-rtti -Wextra -Wpointer-arith
LOCAL_LDFLAGS += -fPIE -pie
LOCAL_C_INCLUDES := $(LOCAL_PATH)
diff --git a/tools/gator/daemon/AnnotateListener.cpp b/tools/gator/daemon/AnnotateListener.cpp
index 5966cbea8d13..d85505634bce 100644
--- a/tools/gator/daemon/AnnotateListener.cpp
+++ b/tools/gator/daemon/AnnotateListener.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/AnnotateListener.h b/tools/gator/daemon/AnnotateListener.h
index 6bc747d42d18..97740b0d6f82 100644
--- a/tools/gator/daemon/AnnotateListener.h
+++ b/tools/gator/daemon/AnnotateListener.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/AtraceDriver.cpp b/tools/gator/daemon/AtraceDriver.cpp
index 2ee7aadf80d1..41a8d7c8ce71 100644
--- a/tools/gator/daemon/AtraceDriver.cpp
+++ b/tools/gator/daemon/AtraceDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
@@ -44,20 +44,19 @@ AtraceDriver::~AtraceDriver() {
void AtraceDriver::readEvents(mxml_node_t *const xml) {
if (access("/system/bin/setprop", X_OK) != 0) {
// Reduce warning noise
- //logg.logSetup("Atrace Disabled\nsetprop is not found, this is not an Android target");
+ //logg.logSetup("Atrace is disabled\nUnable to find setprop, this is not an Android target");
return;
}
if (!gSessionData.mFtraceDriver.isSupported()) {
- logg.logSetup("Atrace Disabled\nftrace support is required");
+ logg.logSetup("Atrace is disabled\nSupport for ftrace is required");
return;
}
-
if (getApplicationFullPath(mNotifyPath, sizeof(mNotifyPath)) != 0) {
logg.logMessage("Unable to determine the full path of gatord, the cwd will be used");
}
strncat(mNotifyPath, "notify.dex", sizeof(mNotifyPath) - strlen(mNotifyPath) - 1);
if (access(mNotifyPath, W_OK) != 0) {
- logg.logSetup("Atrace Disabled\nunable to locate notify.dex");
+ logg.logSetup("Atrace is disabled\nUnable to locate notify.dex");
return;
}
@@ -78,12 +77,17 @@ void AtraceDriver::readEvents(mxml_node_t *const xml) {
continue;
}
- const char *flag = mxmlElementGetAttr(node, "flag");
- if (flag == NULL) {
+ const char *flagStr = mxmlElementGetAttr(node, "flag");
+ if (flagStr == NULL) {
logg.logError("The atrace counter %s is missing the required flag attribute", counter);
handleException();
}
- setCounters(new AtraceCounter(getCounters(), strdup(counter), strtol(flag, NULL, 16)));
+ int flag;
+ if (!stringToInt(&flag, flagStr, 16)) {
+ logg.logError("The flag attribute of the atrace counter %s is not a hex integer", counter);
+ handleException();
+ }
+ setCounters(new AtraceCounter(getCounters(), strdup(counter), flag));
}
}
@@ -96,7 +100,7 @@ void AtraceDriver::setAtrace(const int flags) {
} else if (pid == 0) {
char buf[1<<10];
snprintf(buf, sizeof(buf), "setprop debug.atrace.tags.enableflags %i; "
- "dalvikvm -cp %s com.android.internal.util.WithFramework Notify", flags, mNotifyPath);
+ "CLASSPATH=%s app_process /system/bin Notify", flags, mNotifyPath);
execlp("sh", "sh", "-c", buf, NULL);
exit(0);
}
diff --git a/tools/gator/daemon/AtraceDriver.h b/tools/gator/daemon/AtraceDriver.h
index 0a068580caf3..113468d5fbf0 100644
--- a/tools/gator/daemon/AtraceDriver.h
+++ b/tools/gator/daemon/AtraceDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2015. All rights reserved.
+ * Copyright (C) ARM Limited 2015-2016. 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
diff --git a/tools/gator/daemon/Buffer.cpp b/tools/gator/daemon/Buffer.cpp
index de42232bca86..31a8e66c0046 100644
--- a/tools/gator/daemon/Buffer.cpp
+++ b/tools/gator/daemon/Buffer.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/Buffer.h b/tools/gator/daemon/Buffer.h
index 7dd83494c357..62fb12157e4c 100644
--- a/tools/gator/daemon/Buffer.h
+++ b/tools/gator/daemon/Buffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/CCNDriver.cpp b/tools/gator/daemon/CCNDriver.cpp
index b881e8112ec2..c041d6e43989 100644
--- a/tools/gator/daemon/CCNDriver.cpp
+++ b/tools/gator/daemon/CCNDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/CCNDriver.h b/tools/gator/daemon/CCNDriver.h
index 8a155a7fc837..b614779b04f7 100644
--- a/tools/gator/daemon/CCNDriver.h
+++ b/tools/gator/daemon/CCNDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/CapturedXML.cpp b/tools/gator/daemon/CapturedXML.cpp
index 7a91a79fb768..c350d8f7099e 100644
--- a/tools/gator/daemon/CapturedXML.cpp
+++ b/tools/gator/daemon/CapturedXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/CapturedXML.h b/tools/gator/daemon/CapturedXML.h
index 69d80c09b514..55e1304cf854 100644
--- a/tools/gator/daemon/CapturedXML.h
+++ b/tools/gator/daemon/CapturedXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -21,6 +21,4 @@ private:
mxml_node_t* getTree(bool includeTime);
};
-const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
-
#endif //__CAPTURED_XML_H__
diff --git a/tools/gator/daemon/Child.cpp b/tools/gator/daemon/Child.cpp
index df9fe232cb07..bc6dd6235878 100644
--- a/tools/gator/daemon/Child.cpp
+++ b/tools/gator/daemon/Child.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Child.h b/tools/gator/daemon/Child.h
index a6c54db70a70..804db4bf739d 100644
--- a/tools/gator/daemon/Child.h
+++ b/tools/gator/daemon/Child.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Command.cpp b/tools/gator/daemon/Command.cpp
index e9f230472a54..05f8f89c49db 100644
--- a/tools/gator/daemon/Command.cpp
+++ b/tools/gator/daemon/Command.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/Command.h b/tools/gator/daemon/Command.h
index 2838adcec661..cc4b30754893 100644
--- a/tools/gator/daemon/Command.h
+++ b/tools/gator/daemon/Command.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/Config.h b/tools/gator/daemon/Config.h
index 3c6752eedfdc..b426e9ba0ffd 100644
--- a/tools/gator/daemon/Config.h
+++ b/tools/gator/daemon/Config.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -17,6 +17,8 @@
#define MAX_PERFORMANCE_COUNTERS 50
#define NR_CPUS 32
+#define CLUSTER_COUNT 4
+#define CLUSTER_MASK (CLUSTER_COUNT - 1)
// If debugfs is not mounted at /sys/kernel/debug, update TRACING_PATH
#define TRACING_PATH "/sys/kernel/debug/tracing"
diff --git a/tools/gator/daemon/ConfigurationXML.cpp b/tools/gator/daemon/ConfigurationXML.cpp
index eda487b40e9f..035b5eb3de08 100644
--- a/tools/gator/daemon/ConfigurationXML.cpp
+++ b/tools/gator/daemon/ConfigurationXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -17,22 +17,22 @@
#include "OlyUtility.h"
#include "SessionData.h"
+static const char TAG_CONFIGURATION[] = "configuration";
+
static const char ATTR_COUNTER[] = "counter";
static const char ATTR_REVISION[] = "revision";
static const char ATTR_EVENT[] = "event";
static const char ATTR_COUNT[] = "count";
static const char ATTR_CORES[] = "cores";
+static const char CLUSTER_VAR[] = "${cluster}";
+
ConfigurationXML::ConfigurationXML() {
if (gSessionData.mCountersError != NULL) {
free(gSessionData.mCountersError);
gSessionData.mCountersError = NULL;
}
- const char * configuration_xml;
- unsigned int configuration_xml_len;
- getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
-
char path[PATH_MAX];
getPath(path);
@@ -41,10 +41,7 @@ ConfigurationXML::ConfigurationXML() {
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;
+ mConfigurationXML = getDefaultConfigurationXml();
}
int ret = parse(mConfigurationXML);
@@ -151,7 +148,11 @@ int ConfigurationXML::configurationsTag(mxml_node_t *node) {
return 1; //revision issue;
}
- int revision = strtol(revision_string, NULL, 10);
+ int revision;
+ if (!stringToInt(&revision, revision_string, 10)) {
+ logg.logError("Configuration XML revision must be an integer");
+ handleException();
+ }
if (revision < CONFIGURATION_REVISION) {
return 1; // revision issue
}
@@ -173,9 +174,30 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
Counter & counter = gSessionData.mCounters[mIndex];
counter.clear();
if (mxmlElementGetAttr(node, ATTR_COUNTER)) counter.setType(mxmlElementGetAttr(node, ATTR_COUNTER));
- 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_CORES)) counter.setCores(strtol(mxmlElementGetAttr(node, ATTR_CORES), NULL, 10));
+ if (mxmlElementGetAttr(node, ATTR_EVENT)) {
+ int event;
+ if (!stringToInt(&event, mxmlElementGetAttr(node, ATTR_EVENT), 16)) {
+ logg.logError("Configuration XML event must be an integer");
+ handleException();
+ }
+ counter.setEvent(event);
+ }
+ if (mxmlElementGetAttr(node, ATTR_COUNT)) {
+ int count;
+ if (!stringToInt(&count, mxmlElementGetAttr(node, ATTR_COUNT), 10)) {
+ logg.logError("Configuration XML count must be an integer");
+ handleException();
+ }
+ counter.setCount(count);
+ }
+ if (mxmlElementGetAttr(node, ATTR_CORES)) {
+ int cores;
+ if (!stringToInt(&cores, mxmlElementGetAttr(node, ATTR_CORES), 10)) {
+ logg.logError("Configuration XML cores must be an integer");
+ handleException();
+ }
+ counter.setCores(cores);
+ }
if (counter.getCount() > 0) {
gSessionData.mIsEBS = true;
}
@@ -204,10 +226,32 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
}
}
-void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) {
+char *ConfigurationXML::getDefaultConfigurationXml() {
#include "defaults_xml.h" // defines and initializes char defaults_xml[] and int defaults_xml_len
- xml = (const char *)defaults_xml;
- len = defaults_xml_len;
+ (void)defaults_xml_len;
+
+ // Resolve ${cluster}
+ mxml_node_t *xml = mxmlLoadString(NULL, (const char *)defaults_xml, MXML_NO_CALLBACK);
+ for (mxml_node_t *node = mxmlFindElement(xml, xml, TAG_CONFIGURATION, NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, xml, TAG_CONFIGURATION, NULL, NULL, MXML_DESCEND);
+ node != NULL;
+ node = next, next = mxmlFindElement(node, xml, TAG_CONFIGURATION, NULL, NULL, MXML_DESCEND)) {
+ const char *counter = mxmlElementGetAttr(node, ATTR_COUNTER);
+ if (counter != NULL && strncmp(counter, CLUSTER_VAR, sizeof(CLUSTER_VAR) - 1) == 0) {
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ mxml_node_t *n = mxmlNewElement(mxmlGetParent(node), TAG_CONFIGURATION);
+ copyMxmlElementAttrs(n, node);
+ char buf[1<<7];
+ snprintf(buf, sizeof(buf), "%s%s", gSessionData.mSharedData->mClusters[cluster]->getPmncName(), counter + sizeof(CLUSTER_VAR) - 1);
+ mxmlElementSetAttr(n, ATTR_COUNTER, buf);
+ }
+ mxmlDelete(node);
+ }
+ }
+
+ char *str = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
+ mxmlDelete(xml);
+ return str;
}
void ConfigurationXML::getPath(char* path) {
diff --git a/tools/gator/daemon/ConfigurationXML.h b/tools/gator/daemon/ConfigurationXML.h
index 2677660ae3a3..25a406398ca4 100644
--- a/tools/gator/daemon/ConfigurationXML.h
+++ b/tools/gator/daemon/ConfigurationXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -13,7 +13,7 @@
class ConfigurationXML {
public:
- static void getDefaultConfigurationXml(const char * & xml, unsigned int & len);
+ static char *getDefaultConfigurationXml();
static void getPath(char* path);
static void remove();
diff --git a/tools/gator/daemon/Counter.h b/tools/gator/daemon/Counter.h
index a4c22f571342..db9b10cfa0bb 100644
--- a/tools/gator/daemon/Counter.h
+++ b/tools/gator/daemon/Counter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/DiskIODriver.cpp b/tools/gator/daemon/DiskIODriver.cpp
index 6e72bfc16f57..4f288aa4d3c6 100644
--- a/tools/gator/daemon/DiskIODriver.cpp
+++ b/tools/gator/daemon/DiskIODriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/DiskIODriver.h b/tools/gator/daemon/DiskIODriver.h
index 6ecda5afc25a..445f8ff253bf 100644
--- a/tools/gator/daemon/DiskIODriver.h
+++ b/tools/gator/daemon/DiskIODriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/Driver.cpp b/tools/gator/daemon/Driver.cpp
index 872ab7b02d6a..a88122a3114a 100644
--- a/tools/gator/daemon/Driver.cpp
+++ b/tools/gator/daemon/Driver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/Driver.h b/tools/gator/daemon/Driver.h
index fe20471f3f33..d5ce40ec7869 100644
--- a/tools/gator/daemon/Driver.h
+++ b/tools/gator/daemon/Driver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/DriverSource.cpp b/tools/gator/daemon/DriverSource.cpp
index 92cc0d981a7c..718b650a81af 100644
--- a/tools/gator/daemon/DriverSource.cpp
+++ b/tools/gator/daemon/DriverSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/DriverSource.h b/tools/gator/daemon/DriverSource.h
index 971a4d970e30..90556449b85d 100644
--- a/tools/gator/daemon/DriverSource.h
+++ b/tools/gator/daemon/DriverSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/DynBuf.cpp b/tools/gator/daemon/DynBuf.cpp
index c5cc60de09f6..feb8471d5ed2 100644
--- a/tools/gator/daemon/DynBuf.cpp
+++ b/tools/gator/daemon/DynBuf.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/DynBuf.h b/tools/gator/daemon/DynBuf.h
index 67c06ba4a409..d7865e8132ab 100644
--- a/tools/gator/daemon/DynBuf.h
+++ b/tools/gator/daemon/DynBuf.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/EventsXML.cpp b/tools/gator/daemon/EventsXML.cpp
index 4f44e047ef95..fc1d309fa51c 100644
--- a/tools/gator/daemon/EventsXML.cpp
+++ b/tools/gator/daemon/EventsXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -13,6 +13,17 @@
#include "OlyUtility.h"
#include "SessionData.h"
+static const char TAG_EVENTS[] = "events";
+static const char TAG_CATEGORY[] = "category";
+static const char TAG_COUNTER_SET[] = "counter_set";
+static const char TAG_EVENT[] = "event";
+
+static const char ATTR_COUNTER[] = "counter";
+static const char ATTR_TITLE[] = "title";
+static const char ATTR_NAME[] = "name";
+
+static const char CLUSTER_VAR[] = "${cluster}";
+
class XMLList {
public:
XMLList(XMLList *const prev, mxml_node_t *const node) : mPrev(prev), mNode(node) {}
@@ -79,7 +90,7 @@ mxml_node_t *EventsXML::getTree() {
}
fclose(fl);
- mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
+ mxml_node_t *events = mxmlFindElement(xml, xml, TAG_EVENTS, NULL, NULL, MXML_DESCEND);
if (!events) {
logg.logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML starts with:\n"
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@@ -94,7 +105,7 @@ mxml_node_t *EventsXML::getTree() {
// Make list of all categories in xml
mxml_node_t *node = xml;
while (true) {
- node = mxmlFindElement(node, xml, "category", NULL, NULL, MXML_DESCEND);
+ node = mxmlFindElement(node, xml, TAG_CATEGORY, NULL, NULL, MXML_DESCEND);
if (node == NULL) {
break;
}
@@ -104,7 +115,7 @@ mxml_node_t *EventsXML::getTree() {
// Make list of all events in xml
node = xml;
while (true) {
- node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
+ node = mxmlFindElement(node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND);
if (node == NULL) {
break;
}
@@ -114,7 +125,7 @@ mxml_node_t *EventsXML::getTree() {
// Make list of all counter_sets in xml
node = xml;
while (true) {
- node = mxmlFindElement(node, xml, "counter_set", NULL, NULL, MXML_DESCEND);
+ node = mxmlFindElement(node, xml, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND);
if (node == NULL) {
break;
}
@@ -122,14 +133,55 @@ mxml_node_t *EventsXML::getTree() {
}
}
+ // Handle counter_sets
+ for (mxml_node_t *node = strcmp(mxmlGetElement(append), TAG_COUNTER_SET) == 0 ? append : mxmlFindElement(append, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND);
+ node != NULL;
+ node = next, next = mxmlFindElement(node, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND)) {
+
+ const char *const name = mxmlElementGetAttr(node, ATTR_NAME);
+ if (name == NULL) {
+ logg.logError("Not all event XML counter_sets have the required name attribute");
+ handleException();
+ }
+
+ // Replace any duplicate counter_sets
+ bool replaced = false;
+ for (XMLList *counterSet = counterSetList; counterSet != NULL; counterSet = counterSet->getPrev()) {
+ const char *const name2 = mxmlElementGetAttr(counterSet->getNode(), ATTR_NAME);
+ if (name2 == NULL) {
+ logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
+ handleException();
+ }
+
+ if (strcmp(name, name2) == 0) {
+ logg.logMessage("Replacing counter %s", name);
+ mxml_node_t *parent = mxmlGetParent(counterSet->getNode());
+ mxmlDelete(counterSet->getNode());
+ mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
+ counterSet->setNode(node);
+ replaced = true;
+ break;
+ }
+ }
+
+ if (replaced) {
+ continue;
+ }
+
+ // Add new counter_sets
+ logg.logMessage("Appending counter_set %s", name);
+ mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
+ }
+
// Handle events
- for (mxml_node_t *node = mxmlFindElement(append, append, "event", NULL, NULL, MXML_DESCEND),
- *next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND);
+ for (mxml_node_t *node = mxmlFindElement(append, append, TAG_EVENT, NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, append, TAG_EVENT, NULL, NULL, MXML_DESCEND);
node != NULL;
- node = next, next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND)) {
- const char *const category = mxmlElementGetAttr(mxmlGetParent(node), "name");
- const char *const title = mxmlElementGetAttr(node, "title");
- const char *const name = mxmlElementGetAttr(node, "name");
+ node = next, next = mxmlFindElement(node, append, TAG_EVENT, NULL, NULL, MXML_DESCEND)) {
+ const char *const category = mxmlElementGetAttr(mxmlGetParent(node), ATTR_NAME);
+ const char *const title = mxmlElementGetAttr(node, ATTR_TITLE);
+ const char *const name = mxmlElementGetAttr(node, ATTR_NAME);
if (category == NULL || title == NULL || name == NULL) {
logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
handleException();
@@ -137,9 +189,9 @@ mxml_node_t *EventsXML::getTree() {
// Replace any duplicate events
for (XMLList *event = eventList; event != NULL; event = event->getPrev()) {
- const char *const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), "name");
- const char *const title2 = mxmlElementGetAttr(event->getNode(), "title");
- const char *const name2 = mxmlElementGetAttr(event->getNode(), "name");
+ const char *const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), ATTR_NAME);
+ const char *const title2 = mxmlElementGetAttr(event->getNode(), ATTR_TITLE);
+ const char *const name2 = mxmlElementGetAttr(event->getNode(), ATTR_NAME);
if (category2 == NULL || title2 == NULL || name2 == NULL) {
logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
handleException();
@@ -157,16 +209,16 @@ mxml_node_t *EventsXML::getTree() {
}
// Handle categories
- for (mxml_node_t *node = strcmp(mxmlGetElement(append), "category") == 0 ? append : mxmlFindElement(append, append, "category", NULL, NULL, MXML_DESCEND),
- *next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND);
+ for (mxml_node_t *node = strcmp(mxmlGetElement(append), TAG_CATEGORY) == 0 ? append : mxmlFindElement(append, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND);
node != NULL;
- node = next, next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND)) {
+ node = next, next = mxmlFindElement(node, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND)) {
// After replacing duplicate events, a category may be empty
if (mxmlGetFirstChild(node) == NULL) {
continue;
}
- const char *const name = mxmlElementGetAttr(node, "name");
+ const char *const name = mxmlElementGetAttr(node, ATTR_NAME);
if (name == NULL) {
logg.logError("Not all event XML category nodes have the required name attribute");
handleException();
@@ -175,7 +227,7 @@ mxml_node_t *EventsXML::getTree() {
// Merge identically named categories
bool merged = false;
for (XMLList *category = categoryList; category != NULL; category = category->getPrev()) {
- const char *const name2 = mxmlElementGetAttr(category->getNode(), "name");
+ const char *const name2 = mxmlElementGetAttr(category->getNode(), ATTR_NAME);
if (name2 == NULL) {
logg.logError("Not all event XML category nodes have the required name attribute");
handleException();
@@ -204,47 +256,6 @@ mxml_node_t *EventsXML::getTree() {
mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
}
- // Handle counter_sets
- for (mxml_node_t *node = strcmp(mxmlGetElement(append), "counter_set") == 0 ? append : mxmlFindElement(append, append, "counter_set", NULL, NULL, MXML_DESCEND),
- *next = mxmlFindElement(node, append, "counter_set", NULL, NULL, MXML_DESCEND);
- node != NULL;
- node = next, next = mxmlFindElement(node, append, "counter_set", NULL, NULL, MXML_DESCEND)) {
-
- const char *const name = mxmlElementGetAttr(node, "name");
- if (name == NULL) {
- logg.logError("Not all event XML counter_sets have the required name attribute");
- handleException();
- }
-
- // Replace any duplicate counter_sets
- bool replaced = false;
- for (XMLList *counterSet = counterSetList; counterSet != NULL; counterSet = counterSet->getPrev()) {
- const char *const name2 = mxmlElementGetAttr(counterSet->getNode(), "name");
- if (name2 == NULL) {
- logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
- handleException();
- }
-
- if (strcmp(name, name2) == 0) {
- logg.logMessage("Replacing counter %s", name);
- mxml_node_t *parent = mxmlGetParent(counterSet->getNode());
- mxmlDelete(counterSet->getNode());
- mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
- counterSet->setNode(node);
- replaced = true;
- break;
- }
- }
-
- if (replaced) {
- continue;
- }
-
- // Add new counter_sets
- logg.logMessage("Appending counter_set %s", name);
- mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
- }
-
XMLList::free(eventList);
XMLList::free(categoryList);
XMLList::free(counterSetList);
@@ -252,14 +263,47 @@ mxml_node_t *EventsXML::getTree() {
mxmlDelete(append);
}
+ // Resolve ${cluster}
+ for (mxml_node_t *node = mxmlFindElement(xml, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND),
+ *next = mxmlFindElement(node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND);
+ node != NULL;
+ node = next, next = mxmlFindElement(node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND)) {
+ const char *counter = mxmlElementGetAttr(node, ATTR_COUNTER);
+ if (counter != NULL && strncmp(counter, CLUSTER_VAR, sizeof(CLUSTER_VAR) - 1) == 0) {
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ mxml_node_t *n = mxmlNewElement(mxmlGetParent(node), TAG_EVENT);
+ copyMxmlElementAttrs(n, node);
+ char buf[1<<7];
+ snprintf(buf, sizeof(buf), "%s%s", gSessionData.mSharedData->mClusters[cluster]->getPmncName(), counter + sizeof(CLUSTER_VAR) - 1);
+ mxmlElementSetAttr(n, ATTR_COUNTER, buf);
+ }
+ mxmlDelete(node);
+ }
+ }
+
return xml;
}
+// mxml doesn't have a function to do this, so dip into its private API
+// Copy all the attributes from src to dst
+void copyMxmlElementAttrs(mxml_node_t *dest, mxml_node_t *src) {
+ if (dest == NULL || dest->type != MXML_ELEMENT ||
+ src == NULL || src->type != MXML_ELEMENT)
+ return;
+
+ int i;
+ mxml_attr_t *attr;
+
+ for (i = src->value.element.num_attrs, attr = src->value.element.attrs; i > 0; --i, ++attr) {
+ mxmlElementSetAttr(dest, attr->name, attr->value);
+ }
+}
+
char *EventsXML::getXML() {
mxml_node_t *xml = getTree();
// Add dynamic events from the drivers
- mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
+ mxml_node_t *events = mxmlFindElement(xml, xml, TAG_EVENTS, NULL, NULL, MXML_DESCEND);
if (!events) {
logg.logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML are:\n"
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
diff --git a/tools/gator/daemon/EventsXML.h b/tools/gator/daemon/EventsXML.h
index 2b38fa4364e0..c3ee7c155b96 100644
--- a/tools/gator/daemon/EventsXML.h
+++ b/tools/gator/daemon/EventsXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/ExternalDriver.cpp b/tools/gator/daemon/ExternalDriver.cpp
index a7fbafff5718..ef06fa87e586 100644
--- a/tools/gator/daemon/ExternalDriver.cpp
+++ b/tools/gator/daemon/ExternalDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/ExternalDriver.h b/tools/gator/daemon/ExternalDriver.h
index d88f9e125f9c..ebd9a4cb5aec 100644
--- a/tools/gator/daemon/ExternalDriver.h
+++ b/tools/gator/daemon/ExternalDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/ExternalSource.cpp b/tools/gator/daemon/ExternalSource.cpp
index c6626ce0939f..15eca2c80a76 100644
--- a/tools/gator/daemon/ExternalSource.cpp
+++ b/tools/gator/daemon/ExternalSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/ExternalSource.h b/tools/gator/daemon/ExternalSource.h
index 210be63876d9..c146bfe21d29 100644
--- a/tools/gator/daemon/ExternalSource.h
+++ b/tools/gator/daemon/ExternalSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/FSDriver.cpp b/tools/gator/daemon/FSDriver.cpp
index bd4ef4792d60..1f681505b6db 100644
--- a/tools/gator/daemon/FSDriver.cpp
+++ b/tools/gator/daemon/FSDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/FSDriver.h b/tools/gator/daemon/FSDriver.h
index 63a4e90a2b46..13703ac6b556 100644
--- a/tools/gator/daemon/FSDriver.h
+++ b/tools/gator/daemon/FSDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/Fifo.cpp b/tools/gator/daemon/Fifo.cpp
index 560ace41d1ae..c253b5f43d40 100644
--- a/tools/gator/daemon/Fifo.cpp
+++ b/tools/gator/daemon/Fifo.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Fifo.h b/tools/gator/daemon/Fifo.h
index 01fa11b2f2c4..4ab1464319f8 100644
--- a/tools/gator/daemon/Fifo.h
+++ b/tools/gator/daemon/Fifo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/FtraceDriver.cpp b/tools/gator/daemon/FtraceDriver.cpp
index 4ea3bf1b4072..ca2e00e5472e 100644
--- a/tools/gator/daemon/FtraceDriver.cpp
+++ b/tools/gator/daemon/FtraceDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
@@ -298,7 +298,7 @@ void FtraceDriver::readEvents(mxml_node_t *const xml) {
const int kernelVersion = KERNEL_VERSION(release[0], release[1], release[2]);
if (kernelVersion < KERNEL_VERSION(3, 10, 0)) {
mSupported = false;
- logg.logSetup("Ftrace Disabled\nFor full ftrace functionality please upgrade to Linux 3.10 or later. With user space gator and Linux prior to 3.10, ftrace counters with the tracepoint and arg attributes will be available.");
+ logg.logSetup("Ftrace is disabled\nFor full ftrace functionality please upgrade to Linux 3.10 or later. With user space gator and Linux prior to 3.10, ftrace counters with the tracepoint and arg attributes will be available.");
return;
}
mMonotonicRawSupport = kernelVersion >= KERNEL_VERSION(4, 2, 0);
@@ -306,7 +306,7 @@ void FtraceDriver::readEvents(mxml_node_t *const xml) {
// Is debugfs or tracefs available?
if (access(TRACING_PATH, R_OK) != 0) {
mSupported = false;
- logg.logSetup("Ftrace Disabled\nUnable to locate the tracing directory");
+ logg.logSetup("Ftrace is disabled\nUnable to locate the tracing directory");
return;
}
@@ -347,7 +347,7 @@ void FtraceDriver::readEvents(mxml_node_t *const xml) {
char buf[1<<10];
snprintf(buf, sizeof(buf), EVENTS_PATH "/%s/enable", enable);
if (access(buf, W_OK) != 0) {
- logg.logSetup("%s Disabled\n%s was not found", counter, buf);
+ logg.logSetup("%s is disabled\n%s was not found", counter, buf);
continue;
}
}
diff --git a/tools/gator/daemon/FtraceDriver.h b/tools/gator/daemon/FtraceDriver.h
index 2da5808ed1aa..8bfe79e5f7ff 100644
--- a/tools/gator/daemon/FtraceDriver.h
+++ b/tools/gator/daemon/FtraceDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/HwmonDriver.cpp b/tools/gator/daemon/HwmonDriver.cpp
index de2a25116456..7ce077037c09 100644
--- a/tools/gator/daemon/HwmonDriver.cpp
+++ b/tools/gator/daemon/HwmonDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -174,7 +174,7 @@ HwmonDriver::~HwmonDriver() {
void HwmonDriver::readEvents(mxml_node_t *const) {
int err = sensors_init(NULL);
if (err) {
- logg.logSetup("Libsensors Disabled\nInitialize failed (%d)", err);
+ logg.logSetup("Libsensors is disabled\nInitialize failed (%d)", err);
return;
}
sensors_sysfs_no_scaling = 1;
diff --git a/tools/gator/daemon/HwmonDriver.h b/tools/gator/daemon/HwmonDriver.h
index f15d557051dc..f01a0fe91e4d 100644
--- a/tools/gator/daemon/HwmonDriver.h
+++ b/tools/gator/daemon/HwmonDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/KMod.cpp b/tools/gator/daemon/KMod.cpp
index 307d6feca1e9..b99f96140ee4 100644
--- a/tools/gator/daemon/KMod.cpp
+++ b/tools/gator/daemon/KMod.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/KMod.h b/tools/gator/daemon/KMod.h
index 7f06b4b34b5d..98e288bbb3b2 100644
--- a/tools/gator/daemon/KMod.h
+++ b/tools/gator/daemon/KMod.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/LocalCapture.cpp b/tools/gator/daemon/LocalCapture.cpp
index b529aa19ee94..16b58c4277b0 100644
--- a/tools/gator/daemon/LocalCapture.cpp
+++ b/tools/gator/daemon/LocalCapture.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/LocalCapture.h b/tools/gator/daemon/LocalCapture.h
index 807f49d16845..241d7bdffd4c 100644
--- a/tools/gator/daemon/LocalCapture.h
+++ b/tools/gator/daemon/LocalCapture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Logging.cpp b/tools/gator/daemon/Logging.cpp
index ba5e315e548c..956d3b19f169 100644
--- a/tools/gator/daemon/Logging.cpp
+++ b/tools/gator/daemon/Logging.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Logging.h b/tools/gator/daemon/Logging.h
index 37d3a6f32799..e4b04e3a4740 100644
--- a/tools/gator/daemon/Logging.h
+++ b/tools/gator/daemon/Logging.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/MaliVideoDriver.cpp b/tools/gator/daemon/MaliVideoDriver.cpp
index f72acfdf2a86..44638723b2d0 100644
--- a/tools/gator/daemon/MaliVideoDriver.cpp
+++ b/tools/gator/daemon/MaliVideoDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
@@ -13,6 +13,7 @@
#include "Buffer.h"
#include "Counter.h"
#include "Logging.h"
+#include "OlyUtility.h"
#include "SessionData.h"
// From instr/src/mve_instr_comm_protocol.h
@@ -69,13 +70,25 @@ void MaliVideoDriver::readEvents(mxml_node_t *const xml) {
if (counter == NULL) {
// Ignore
} else if (strncmp(counter, COUNTER, sizeof(COUNTER) - 1) == 0) {
- const int i = strtol(counter + sizeof(COUNTER) - 1, NULL, 10);
+ int i;
+ if (!stringToInt(&i, counter + sizeof(COUNTER) - 1, 10)) {
+ logg.logError("The counter attribute of the Mali video counter %s is not an integer", counter);
+ handleException();
+ }
setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_COUNTER, i));
} else if (strncmp(counter, EVENT, sizeof(EVENT) - 1) == 0) {
- const int i = strtol(counter + sizeof(EVENT) - 1, NULL, 10);
+ int i;
+ if (!stringToInt(&i, counter + sizeof(EVENT) - 1, 10)) {
+ logg.logError("The event attribute of the Mali video counter %s is not an integer", counter);
+ handleException();
+ }
setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_EVENT, i));
} else if (strncmp(counter, ACTIVITY, sizeof(ACTIVITY) - 1) == 0) {
- const int i = strtol(counter + sizeof(ACTIVITY) - 1, NULL, 10);
+ int i;
+ if (!stringToInt(&i, counter + sizeof(ACTIVITY) - 1, 10)) {
+ logg.logError("The activity attribute of the Mali video counter %s is not an integer", counter);
+ handleException();
+ }
setCounters(new MaliVideoCounter(getCounters(), strdup(counter), MVCT_ACTIVITY, i));
}
}
diff --git a/tools/gator/daemon/MaliVideoDriver.h b/tools/gator/daemon/MaliVideoDriver.h
index fd01b1b2d85b..1a9c2e1f25cf 100644
--- a/tools/gator/daemon/MaliVideoDriver.h
+++ b/tools/gator/daemon/MaliVideoDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
diff --git a/tools/gator/daemon/MemInfoDriver.cpp b/tools/gator/daemon/MemInfoDriver.cpp
index bc02107a47a6..48e3bedad4ff 100644
--- a/tools/gator/daemon/MemInfoDriver.cpp
+++ b/tools/gator/daemon/MemInfoDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -36,7 +36,7 @@ int64_t MemInfoCounter::read() {
return *mValue;
}
-MemInfoDriver::MemInfoDriver() : mBuf(), mMemUsed(0), mMemFree(0), mBuffers(0) {
+MemInfoDriver::MemInfoDriver() : mBuf(), mMemUsed(0), mMemFree(0), mBuffers(0), mCached(0), mSlab(0) {
}
MemInfoDriver::~MemInfoDriver() {
@@ -51,6 +51,8 @@ void MemInfoDriver::readEvents(mxml_node_t *const) {
setCounters(new MemInfoCounter(getCounters(), strdup("Linux_meminfo_memused2"), &mMemUsed));
setCounters(new MemInfoCounter(getCounters(), strdup("Linux_meminfo_memfree"), &mMemFree));
setCounters(new MemInfoCounter(getCounters(), strdup("Linux_meminfo_bufferram"), &mBuffers));
+ setCounters(new MemInfoCounter(getCounters(), strdup("Linux_meminfo_cached"), &mCached));
+ setCounters(new MemInfoCounter(getCounters(), strdup("Linux_meminfo_slab"), &mSlab));
}
void MemInfoDriver::read(Buffer *const buffer) {
@@ -79,6 +81,10 @@ void MemInfoDriver::read(Buffer *const buffer) {
mMemFree = strtoll(colon + 1, NULL, 10) << 10;
} else if (strcmp(key, "Buffers") == 0) {
mBuffers = strtoll(colon + 1, NULL, 10) << 10;
+ } else if (strcmp(key, "Cached") == 0) {
+ mCached = strtoll(colon + 1, NULL, 10) << 10;
+ } else if (strcmp(key, "Slab") == 0) {
+ mSlab = strtoll(colon + 1, NULL, 10) << 10;
}
if (end == NULL) {
diff --git a/tools/gator/daemon/MemInfoDriver.h b/tools/gator/daemon/MemInfoDriver.h
index ffeaf3009e93..6d58860eefec 100644
--- a/tools/gator/daemon/MemInfoDriver.h
+++ b/tools/gator/daemon/MemInfoDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -28,6 +28,8 @@ private:
int64_t mMemUsed;
int64_t mMemFree;
int64_t mBuffers;
+ int64_t mCached;
+ int64_t mSlab;
// Intentionally unimplemented
MemInfoDriver(const MemInfoDriver &);
diff --git a/tools/gator/daemon/MidgardDriver.cpp b/tools/gator/daemon/MidgardDriver.cpp
index 58ea868698d1..db4763b9255d 100644
--- a/tools/gator/daemon/MidgardDriver.cpp
+++ b/tools/gator/daemon/MidgardDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -131,11 +131,9 @@ void MidgardDriver::query() const {
PacketHeader header;
const size_t bufSize = sizeof(gSessionData.mSharedData->mMaliMidgardCounters);
bool first = true;
- // [DR] Do something with this
//uint32_t compatibilityTiebreak = 0;
while (true) {
- // [DR] Store-and-forward data at capture start?
if (!readAll(uds, &header, sizeof(PacketHeader))) {
logg.logError("Unable to read Midgard header");
handleException();
diff --git a/tools/gator/daemon/MidgardDriver.h b/tools/gator/daemon/MidgardDriver.h
index 503898595372..b04730d88d98 100644
--- a/tools/gator/daemon/MidgardDriver.h
+++ b/tools/gator/daemon/MidgardDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Monitor.cpp b/tools/gator/daemon/Monitor.cpp
index c71870badcf8..a2cc98af1d92 100644
--- a/tools/gator/daemon/Monitor.cpp
+++ b/tools/gator/daemon/Monitor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/Monitor.h b/tools/gator/daemon/Monitor.h
index 55368fca3e0a..3fbb7845f13c 100644
--- a/tools/gator/daemon/Monitor.h
+++ b/tools/gator/daemon/Monitor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/NetDriver.cpp b/tools/gator/daemon/NetDriver.cpp
index 50a187da5799..87e3d5611a82 100644
--- a/tools/gator/daemon/NetDriver.cpp
+++ b/tools/gator/daemon/NetDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/NetDriver.h b/tools/gator/daemon/NetDriver.h
index 5f722800f75f..be8b345c62e3 100644
--- a/tools/gator/daemon/NetDriver.h
+++ b/tools/gator/daemon/NetDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/OlySocket.cpp b/tools/gator/daemon/OlySocket.cpp
index 2cd5a599f450..1b4a32e261b2 100644
--- a/tools/gator/daemon/OlySocket.cpp
+++ b/tools/gator/daemon/OlySocket.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/OlySocket.h b/tools/gator/daemon/OlySocket.h
index dcd557dad3db..3f8baa6f7e4c 100644
--- a/tools/gator/daemon/OlySocket.h
+++ b/tools/gator/daemon/OlySocket.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/OlyUtility.cpp b/tools/gator/daemon/OlyUtility.cpp
index 30655f0538dd..d508b97c83de 100644
--- a/tools/gator/daemon/OlyUtility.cpp
+++ b/tools/gator/daemon/OlyUtility.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -8,10 +8,11 @@
#include "OlyUtility.h"
+#include <ctype.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#if defined(WIN32)
#include <windows.h>
@@ -61,6 +62,42 @@ void stringToLower(char* string) {
}
}
+bool stringToLongLong(long long *const value, const char *str, const int base) {
+ char *endptr;
+ long long v;
+ errno = 0;
+ v = strtoll(str, &endptr, base);
+ if (errno != 0 || *endptr != '\0') {
+ return false;
+ }
+ *value = v;
+
+ return true;
+}
+
+bool stringToLong(long *const value, const char *str, const int base) {
+ char *endptr;
+ long v;
+ errno = 0;
+ v = strtol(str, &endptr, base);
+ if (errno != 0 || *endptr != '\0') {
+ return false;
+ }
+ *value = v;
+
+ return true;
+}
+
+bool stringToInt(int *const value, const char *str, const int base) {
+ long v;
+ if (!stringToLong(&v, str, base)) {
+ return false;
+ }
+ *value = v;
+
+ return true;
+}
+
// Modifies fullpath with the path part including the trailing path separator
int getApplicationFullPath(char* fullpath, int sizeOfPath) {
memset(fullpath, 0, sizeOfPath);
diff --git a/tools/gator/daemon/OlyUtility.h b/tools/gator/daemon/OlyUtility.h
index fc10e3516419..307c7adbdaef 100644
--- a/tools/gator/daemon/OlyUtility.h
+++ b/tools/gator/daemon/OlyUtility.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -14,7 +14,9 @@
#ifdef WIN32
#define PATH_SEPARATOR '\\'
#define CAIMAN_PATH_MAX MAX_PATH
+#if !defined(_MSC_VER) || _MSC_VER < 1900
#define snprintf _snprintf
+#endif
#else
#include <limits.h>
#define PATH_SEPARATOR '/'
@@ -23,6 +25,9 @@
bool stringToBool(const char* string, bool defValue);
void stringToLower(char* string);
+bool stringToLongLong(long long *const value, const char *str, const int base);
+bool stringToLong(long *const value, const char *str, const int base);
+bool stringToInt(int *const value, const char *str, const int base);
int getApplicationFullPath(char* path, int sizeOfPath);
char* readFromDisk(const char* file, unsigned int *size = NULL, bool appendNull = true);
int writeToDisk(const char* path, const char* file);
diff --git a/tools/gator/daemon/PerfBuffer.cpp b/tools/gator/daemon/PerfBuffer.cpp
index a369688c0619..00c098ca1e02 100644
--- a/tools/gator/daemon/PerfBuffer.cpp
+++ b/tools/gator/daemon/PerfBuffer.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/PerfBuffer.h b/tools/gator/daemon/PerfBuffer.h
index 32cc0625456d..9e1777b72dd7 100644
--- a/tools/gator/daemon/PerfBuffer.h
+++ b/tools/gator/daemon/PerfBuffer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/PerfDriver.cpp b/tools/gator/daemon/PerfDriver.cpp
index 2c78cbfe22ef..3d4e54688c62 100644
--- a/tools/gator/daemon/PerfDriver.cpp
+++ b/tools/gator/daemon/PerfDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -28,9 +28,11 @@
#define TYPE_DERIVED ~0U
+static GatorCpu gatorCpuOther("Other", "Other", NULL, 0xfffff, 6);
+
class PerfCounter : public DriverCounter {
public:
- PerfCounter(DriverCounter *next, const char *name, uint32_t type, uint64_t config, uint64_t sampleType, uint64_t flags, const int count) : DriverCounter(next, name), mType(type), mConfig(config), mSampleType(sampleType), mFlags(flags), mCount(count) {}
+ PerfCounter(DriverCounter *next, const char *name, uint32_t type, uint64_t config, uint64_t sampleType, uint64_t flags, const GatorCpu *const cluster, const int count) : DriverCounter(next, name), mType(type), mConfig(config), mSampleType(sampleType), mFlags(flags), mCluster(cluster), mCount(count) {}
~PerfCounter() {
}
@@ -43,6 +45,7 @@ public:
uint64_t getSampleType() const { return mSampleType; }
void setSampleType(uint64_t sampleType) { mSampleType = sampleType; }
uint64_t getFlags() const { return mFlags; }
+ const GatorCpu *getCluster() const { return mCluster; }
virtual void read(Buffer *const, const int) {}
private:
@@ -50,6 +53,7 @@ private:
uint64_t mConfig;
uint64_t mSampleType;
const uint64_t mFlags;
+ const GatorCpu *const mCluster;
int mCount;
// Intentionally undefined
@@ -59,9 +63,13 @@ private:
class CPUFreqDriver : public PerfCounter {
public:
- CPUFreqDriver(DriverCounter *next, uint64_t id) : PerfCounter(next, strdup("Linux_power_cpu_freq"), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU, 1) {}
+ CPUFreqDriver(DriverCounter *next, const char *name, uint64_t id, const GatorCpu *const cluster) : PerfCounter(next, name, PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU, cluster, 1) {}
void read(Buffer *const buffer, const int cpu) {
+ if (gSessionData.mSharedData->mClusters[gSessionData.mSharedData->mClusterIds[cpu]] != getCluster()) {
+ return;
+ }
+
char buf[64];
snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%i/cpufreq/cpuinfo_cur_freq", cpu);
@@ -102,17 +110,24 @@ private:
PerfTracepoint &operator=(const PerfTracepoint &);
};
-void PerfDriver::addCpuCounters(const char *const counterName, const int type, const int numCounters) {
- int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
+void PerfDriver::addCpuCounters(const GatorCpu *const cpu) {
+ int cluster = gSessionData.mSharedData->mClusterCount++;
+ if (cluster >= ARRAY_LENGTH(gSessionData.mSharedData->mClusters)) {
+ logg.logError("Too many clusters on the target, please increase CLUSTER_COUNT in Config.h");
+ handleException();
+ }
+ gSessionData.mSharedData->mClusters[cluster] = cpu;
+
+ int len = snprintf(NULL, 0, "%s_ccnt", cpu->getPmncName()) + 1;
char *name = new char[len];
- snprintf(name, len, "%s_ccnt", counterName);
- setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, 0));
+ snprintf(name, len, "%s_ccnt", cpu->getPmncName());
+ setCounters(new PerfCounter(getCounters(), name, cpu->getType(), -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, cpu, 0));
- for (int j = 0; j < numCounters; ++j) {
- len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
+ for (int j = 0; j < cpu->getPmncCounters(); ++j) {
+ len = snprintf(NULL, 0, "%s_cnt%d", cpu->getPmncName(), j) + 1;
name = new char[len];
- snprintf(name, len, "%s_cnt%d", counterName, j);
- setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, 0));
+ snprintf(name, len, "%s_cnt%d", cpu->getPmncName(), j);
+ setCounters(new PerfCounter(getCounters(), name, cpu->getType(), -1, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, cpu, 0));
}
}
@@ -124,21 +139,21 @@ void PerfDriver::addUncoreCounters(const char *const counterName, const int type
len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
name = new char[len];
snprintf(name, len, "%s_ccnt", counterName);
- setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0, 0));
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0, NULL, 0));
}
for (int j = 0; j < numCounters; ++j) {
len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
name = new char[len];
snprintf(name, len, "%s_cnt%d", counterName, j);
- setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0, 0));
+ setCounters(new PerfCounter(getCounters(), name, type, -1, PERF_SAMPLE_READ, 0, NULL, 0));
}
}
long long PerfDriver::getTracepointId(const char *const counter, const char *const name, DynBuf *const printb) {
long long result = PerfDriver::getTracepointId(name, printb);
if (result <= 0) {
- logg.logSetup("%s Disabled\n%s was not found", counter, printb->getBuf());
+ logg.logSetup("%s is disabled\n%s was not found", counter, printb->getBuf());
}
return result;
}
@@ -183,7 +198,7 @@ void PerfDriver::readEvents(mxml_node_t *const xml) {
long long id = getTracepointId(counter, tracepoint, &printb);
if (id >= 0) {
logg.logMessage("Using perf for %s", counter);
- setCounters(new PerfCounter(getCounters(), strdup(counter), PERF_TYPE_TRACEPOINT, id, arg == NULL ? 0 : PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU, 1));
+ setCounters(new PerfCounter(getCounters(), strdup(counter), PERF_TYPE_TRACEPOINT, id, arg == NULL ? 0 : PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU | PERF_GROUP_ALL_CLUSTERS, NULL, 1));
mTracepoints = new PerfTracepoint(mTracepoints, getCounters(), strdup(tracepoint));
}
}
@@ -229,7 +244,8 @@ bool PerfDriver::setup() {
if (DriverSource::readIntDriver(buf, &type) == 0) {
foundCpu = true;
logg.logMessage("Adding cpu counters for %s with type %i", gatorCpu->getCoreName(), type);
- addCpuCounters(gatorCpu->getPmncName(), type, gatorCpu->getPmncCounters());
+ gatorCpu->setType(type);
+ addCpuCounters(gatorCpu);
continue;
}
}
@@ -253,46 +269,69 @@ bool PerfDriver::setup() {
if (gatorCpu != NULL) {
foundCpu = true;
logg.logMessage("Adding cpu counters (based on cpuid) for %s", gatorCpu->getCoreName());
- addCpuCounters(gatorCpu->getPmncName(), PERF_TYPE_RAW, gatorCpu->getPmncCounters());
+ gatorCpu->setType(PERF_TYPE_RAW);
+ addCpuCounters(gatorCpu);
}
}
if (!foundCpu) {
logCpuNotFound();
#if defined(__arm__) || defined(__aarch64__)
- addCpuCounters("Other", PERF_TYPE_RAW, 6);
+ gatorCpuOther.setType(PERF_TYPE_RAW);
+ addCpuCounters(&gatorCpuOther);
#endif
}
+ if (gSessionData.mSharedData->mClusterCount == 0) {
+ gSessionData.mSharedData->mClusters[gSessionData.mSharedData->mClusterCount++] = &gatorCpuOther;
+ }
+ // Reread cpuinfo so that cluster data is recalculated
+ gSessionData.readCpuInfo();
+
// Add supported software counters
long long id;
DynBuf printb;
+ char buf[40];
- id = getTracepointId("Linux_irq_softirq", "irq/softirq_exit", &printb);
+ id = getTracepointId("Interrupts: SoftIRQ", "irq/softirq_exit", &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), strdup("Linux_irq_softirq"), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, 0));
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ snprintf(buf, sizeof(buf), "%s_softirq", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new PerfCounter(getCounters(), strdup(buf), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, gSessionData.mSharedData->mClusters[cluster], 0));
+ }
}
- id = getTracepointId("Linux_irq_irq", "irq/irq_handler_exit", &printb);
+ id = getTracepointId("Interrupts: IRQ", "irq/irq_handler_exit", &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), strdup("Linux_irq_irq"), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, 0));
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ snprintf(buf, sizeof(buf), "%s_irq", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new PerfCounter(getCounters(), strdup(buf), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, gSessionData.mSharedData->mClusters[cluster], 0));
+ }
}
- id = getTracepointId("Linux_sched_switch", SCHED_SWITCH, &printb);
+ id = getTracepointId("Scheduler: Switch", SCHED_SWITCH, &printb);
if (id >= 0) {
- setCounters(new PerfCounter(getCounters(), strdup("Linux_sched_switch"), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, 0));
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ snprintf(buf, sizeof(buf), "%s_switch", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new PerfCounter(getCounters(), strdup(buf), PERF_TYPE_TRACEPOINT, id, PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU, gSessionData.mSharedData->mClusters[cluster], 0));
+ }
}
- id = getTracepointId("Linux_power_cpu_freq", CPU_FREQUENCY, &printb);
+ id = getTracepointId("Clock: Frequency", CPU_FREQUENCY, &printb);
if (id >= 0 && access("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq", R_OK) == 0) {
- setCounters(new CPUFreqDriver(getCounters(), id));
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ snprintf(buf, sizeof(buf), "%s_freq", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new CPUFreqDriver(getCounters(), strdup(buf), id, gSessionData.mSharedData->mClusters[cluster]));
+ }
}
- setCounters(new PerfCounter(getCounters(), strdup("Linux_cpu_wait_contention"), TYPE_DERIVED, -1, 0, 0, 0));
- setCounters(new PerfCounter(getCounters(), strdup("Linux_cpu_system"), TYPE_DERIVED, -1, 0, 0, 0));
- setCounters(new PerfCounter(getCounters(), strdup("Linux_cpu_user"), TYPE_DERIVED, -1, 0, 0, 0));
-
- //Linux_cpu_wait_io
+ setCounters(new PerfCounter(getCounters(), strdup("Linux_cpu_wait_contention"), TYPE_DERIVED, -1, 0, 0, NULL, 0));
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ snprintf(buf, sizeof(buf), "%s_system", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new PerfCounter(getCounters(), strdup(buf), TYPE_DERIVED, -1, 0, 0, NULL, 0));
+ snprintf(buf, sizeof(buf), "%s_user", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ setCounters(new PerfCounter(getCounters(), strdup(buf), TYPE_DERIVED, -1, 0, 0, NULL, 0));
+ }
mIsSetup = true;
return true;
@@ -388,7 +427,7 @@ void PerfDriver::setupCounter(Counter &counter) {
bool PerfDriver::enable(const uint64_t currTime, PerfGroup *const group, Buffer *const buffer) const {
for (PerfCounter *counter = static_cast<PerfCounter *>(getCounters()); counter != NULL; counter = static_cast<PerfCounter *>(counter->getNext())) {
if (counter->isEnabled() && (counter->getType() != TYPE_DERIVED) &&
- !group->add(currTime, buffer, counter->getKey(), counter->getType(), counter->getConfig(), counter->getCount(), counter->getSampleType(), counter->getFlags())) {
+ !group->add(currTime, buffer, counter->getKey(), counter->getType(), counter->getConfig(), counter->getCount(), counter->getSampleType(), counter->getFlags(), counter->getCluster())) {
logg.logMessage("PerfGroup::add failed");
return false;
}
diff --git a/tools/gator/daemon/PerfDriver.h b/tools/gator/daemon/PerfDriver.h
index c6d81263e8ec..35411e82d067 100644
--- a/tools/gator/daemon/PerfDriver.h
+++ b/tools/gator/daemon/PerfDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -19,6 +19,7 @@
class Buffer;
class DynBuf;
+class GatorCpu;
class PerfGroup;
class PerfTracepoint;
@@ -46,7 +47,7 @@ public:
static long long getTracepointId(const char *const counter, const char *const name, DynBuf *const printb);
private:
- void addCpuCounters(const char *const counterName, const int type, const int numCounters);
+ void addCpuCounters(const GatorCpu *const cpu);
void addUncoreCounters(const char *const counterName, const int type, const int numCounters, const bool hasCyclesCounter);
int mIsSetup : 1,
diff --git a/tools/gator/daemon/PerfGroup.cpp b/tools/gator/daemon/PerfGroup.cpp
index 25999e55b662..a220e6768473 100644
--- a/tools/gator/daemon/PerfGroup.cpp
+++ b/tools/gator/daemon/PerfGroup.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -59,6 +59,7 @@ static int sys_perf_event_open(struct perf_event_attr *const attr, const pid_t p
PerfGroup::PerfGroup(PerfBuffer *const pb) : mPb(pb), mSchedSwitchId(-1) {
memset(&mAttrs, 0, sizeof(mAttrs));
memset(&mFlags, 0, sizeof(mFlags));
+ memset(&mClusters, 0, sizeof(mClusters));
memset(&mKeys, -1, sizeof(mKeys));
memset(&mFds, -1, sizeof(mFds));
memset(&mLeaders, -1, sizeof(mLeaders));
@@ -72,7 +73,7 @@ PerfGroup::~PerfGroup() {
}
}
-int PerfGroup::doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags) {
+int PerfGroup::doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags, const GatorCpu *const cluster) {
int i;
for (i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
if (mKeys[i] < 0) {
@@ -97,6 +98,7 @@ int PerfGroup::doAdd(const uint64_t currTime, Buffer *const buffer, const int ke
mAttrs[i].task = (flags & PERF_GROUP_TASK ? 1 : 0);
mAttrs[i].sample_id_all = (flags & PERF_GROUP_SAMPLE_ID_ALL ? 1 : 0);
mFlags[i] = flags;
+ mClusters[i] = cluster;
mKeys[i] = key;
@@ -130,19 +132,19 @@ bool PerfGroup::createCpuGroup(const uint64_t currTime, Buffer *const buffer) {
}
}
- mLeaders[PERF_TYPE_HARDWARE] = doAdd(currTime, buffer, schedSwitchKey, PERF_TYPE_TRACEPOINT, mSchedSwitchId, 1, PERF_SAMPLE_READ | PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU | PERF_GROUP_LEADER | PERF_GROUP_CPU);
+ mLeaders[PERF_TYPE_HARDWARE] = doAdd(currTime, buffer, schedSwitchKey, PERF_TYPE_TRACEPOINT, mSchedSwitchId, 1, PERF_SAMPLE_READ | PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU | PERF_GROUP_LEADER | PERF_GROUP_CPU | PERF_GROUP_ALL_CLUSTERS, NULL);
if (mLeaders[PERF_TYPE_HARDWARE] < 0) {
return false;
}
- if (gSessionData.mSampleRate > 0 && !gSessionData.mIsEBS && doAdd(currTime, buffer, INT_MAX-PERF_TYPE_HARDWARE, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData.mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU) < 0) {
+ if (gSessionData.mSampleRate > 0 && !gSessionData.mIsEBS && doAdd(currTime, buffer, INT_MAX-PERF_TYPE_HARDWARE, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData.mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_READ, PERF_GROUP_PER_CPU | PERF_GROUP_CPU | PERF_GROUP_ALL_CLUSTERS, NULL) < 0) {
return false;
}
return true;
}
-bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags) {
+bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags, const GatorCpu *const cluster) {
const int effectiveType = getEffectiveType(type, flags);
// Does a group exist for this already?
@@ -155,7 +157,7 @@ bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key
} else {
// Non-CPU PMUs are sampled every 100ms for Sample Rate: None and EBS, otherwise they would never be sampled
const uint64_t timeout = gSessionData.mSampleRate > 0 && !gSessionData.mIsEBS ? 1000000000UL / gSessionData.mSampleRate : 100000000UL;
- mLeaders[effectiveType] = doAdd(currTime, buffer, INT_MAX-effectiveType, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, timeout, PERF_SAMPLE_READ, PERF_GROUP_LEADER);
+ mLeaders[effectiveType] = doAdd(currTime, buffer, INT_MAX-effectiveType, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, timeout, PERF_SAMPLE_READ, PERF_GROUP_LEADER, NULL);
if (mLeaders[effectiveType] < 0) {
return false;
}
@@ -167,7 +169,7 @@ bool PerfGroup::add(const uint64_t currTime, Buffer *const buffer, const int key
handleException();
}
- return doAdd(currTime, buffer, key, type, config, sample, sampleType, flags) >= 0;
+ return doAdd(currTime, buffer, key, type, config, sample, sampleType, flags, cluster) >= 0;
}
int PerfGroup::prepareCPU(const int cpu, Monitor *const monitor) {
@@ -182,6 +184,10 @@ int PerfGroup::prepareCPU(const int cpu, Monitor *const monitor) {
continue;
}
+ if ((mFlags[i] & PERF_GROUP_PER_CPU) && !(mFlags[i] & PERF_GROUP_ALL_CLUSTERS) && gSessionData.mSharedData->mClusters[gSessionData.mSharedData->mClusterIds[cpu]] != mClusters[i]) {
+ continue;
+ }
+
const int offset = i * gSessionData.mCores + cpu;
if (mFds[offset] >= 0) {
logg.logMessage("cpu already online or not correctly cleaned up");
diff --git a/tools/gator/daemon/PerfGroup.h b/tools/gator/daemon/PerfGroup.h
index 13a18c348603..aa71b019766d 100644
--- a/tools/gator/daemon/PerfGroup.h
+++ b/tools/gator/daemon/PerfGroup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -17,6 +17,7 @@
#include "Config.h"
class Buffer;
+class GatorCpu;
class Monitor;
class PerfBuffer;
@@ -29,6 +30,7 @@ enum PerfGroupFlags {
PERF_GROUP_PER_CPU = 1 << 5,
PERF_GROUP_LEADER = 1 << 6,
PERF_GROUP_CPU = 1 << 7,
+ PERF_GROUP_ALL_CLUSTERS = 1 << 8,
};
enum {
@@ -43,7 +45,7 @@ public:
~PerfGroup();
bool createCpuGroup(const uint64_t currTime, Buffer *const buffer);
- bool add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags);
+ bool add(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags, const GatorCpu *const cluster);
// Safe to call concurrently
int prepareCPU(const int cpu, Monitor *const monitor);
// Not safe to call concurrently. Returns the number of events enabled
@@ -54,15 +56,16 @@ public:
private:
int getEffectiveType(const int type, const int flags);
- int doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags);
+ int doAdd(const uint64_t currTime, Buffer *const buffer, const int key, const __u32 type, const __u64 config, const __u64 sample, const __u64 sampleType, const int flags, const GatorCpu *const cluster);
// 2* to be conservative for sched_switch, cpu_idle, hrtimer and non-CPU groups
struct perf_event_attr mAttrs[2*MAX_PERFORMANCE_COUNTERS];
PerfBuffer *const mPb;
+ const GatorCpu *mClusters[2*MAX_PERFORMANCE_COUNTERS];
int mFlags[2*MAX_PERFORMANCE_COUNTERS];
int mKeys[2*MAX_PERFORMANCE_COUNTERS];
int mFds[NR_CPUS * (2*MAX_PERFORMANCE_COUNTERS)];
- // Offset in mAttrs, mFlags and mKeys of the group leaders for each perf type
+ // Offset in mAttrs, mFlags, mClusters and mKeys of the group leaders for each perf type
int mLeaders[16];
int mSchedSwitchId;
diff --git a/tools/gator/daemon/PerfSource.cpp b/tools/gator/daemon/PerfSource.cpp
index 75783961b6b8..f0462deb1b2b 100644
--- a/tools/gator/daemon/PerfSource.cpp
+++ b/tools/gator/daemon/PerfSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -8,8 +8,6 @@
#include "PerfSource.h"
-#include <dirent.h>
-#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/prctl.h>
@@ -21,6 +19,7 @@
#include "Child.h"
#include "DynBuf.h"
#include "Logging.h"
+#include "OlyUtility.h"
#include "PerfDriver.h"
#include "Proc.h"
#include "SessionData.h"
@@ -80,48 +79,7 @@ static void *syncFunc(void *arg)
return NULL;
}
-static long getMaxCoreNum() {
- DIR *dir = opendir("/sys/devices/system/cpu");
- if (dir == NULL) {
- logg.logError("Unable to determine the number of cores on the target, opendir failed");
- handleException();
- }
-
- long maxCoreNum = -1;
- struct dirent *dirent;
- while ((dirent = readdir(dir)) != NULL) {
- if (strncmp(dirent->d_name, "cpu", 3) == 0) {
- char *endptr;
- errno = 0;
- long coreNum = strtol(dirent->d_name + 3, &endptr, 10);
- if ((errno == 0) && (*endptr == '\0') && (coreNum >= maxCoreNum)) {
- maxCoreNum = coreNum + 1;
- }
- }
- }
- closedir(dir);
-
- if (maxCoreNum < 1) {
- logg.logError("Unable to determine the number of cores on the target, no cpu# directories found");
- handleException();
- }
-
- if (maxCoreNum >= NR_CPUS) {
- logg.logError("Too many cores on the target, please increase NR_CPUS in Config.h");
- handleException();
- }
-
- return maxCoreNum;
-}
-
PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAME_SUMMARY, 1024, senderSem), mBuffer(NULL), mCountersBuf(), mCountersGroup(&mCountersBuf), mMonitor(), mUEvent(), mSenderSem(senderSem), mStartProfile(startProfile), mInterruptFd(-1), mIsDone(false) {
- long l = sysconf(_SC_PAGE_SIZE);
- if (l < 0) {
- logg.logError("Unable to obtain the page size");
- handleException();
- }
- gSessionData.mPageSize = static_cast<int>(l);
- gSessionData.mCores = static_cast<int>(getMaxCoreNum());
}
PerfSource::~PerfSource() {
@@ -151,7 +109,7 @@ bool PerfSource::prepare() {
|| !gSessionData.mPerf.sendTracepointFormats(currTime, mBuffer, &printb, &b1)
|| !mCountersGroup.createCpuGroup(currTime, mBuffer)
- || !mCountersGroup.add(currTime, mBuffer, cpuIdleKey, PERF_TYPE_TRACEPOINT, cpuIdleId, 1, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU)
+ || !mCountersGroup.add(currTime, mBuffer, cpuIdleKey, PERF_TYPE_TRACEPOINT, cpuIdleId, 1, PERF_SAMPLE_RAW, PERF_GROUP_LEADER | PERF_GROUP_PER_CPU | PERF_GROUP_ALL_CLUSTERS, NULL)
|| !gSessionData.mPerf.enable(currTime, &mCountersGroup, mBuffer)
|| 0) {
@@ -359,11 +317,9 @@ bool PerfSource::handleUEvent(const uint64_t currTime) {
logg.logMessage("Unexpected cpu DEVPATH format");
return false;
}
- char *endptr;
- errno = 0;
- int cpu = strtol(result.mDevPath + sizeof(CPU_DEVPATH) - 1, &endptr, 10);
- if (errno != 0 || *endptr != '\0') {
- logg.logMessage("strtol failed");
+ int cpu;
+ if (!stringToInt(&cpu, result.mDevPath + sizeof(CPU_DEVPATH) - 1, 10)) {
+ logg.logMessage("stringToInt failed");
return false;
}
diff --git a/tools/gator/daemon/PerfSource.h b/tools/gator/daemon/PerfSource.h
index feec1c269922..a7d98ecf5196 100644
--- a/tools/gator/daemon/PerfSource.h
+++ b/tools/gator/daemon/PerfSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/PmuXML.cpp b/tools/gator/daemon/PmuXML.cpp
index 4a4575e34446..8ea716be2652 100644
--- a/tools/gator/daemon/PmuXML.cpp
+++ b/tools/gator/daemon/PmuXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -8,6 +8,8 @@
#include "PmuXML.h"
+#include <dirent.h>
+#include <sys/types.h>
#include <unistd.h>
#include "mxml/mxml.h"
@@ -62,11 +64,19 @@ void PmuXML::parse(const char *const xml) {
node = mxmlFindElement(node, root, TAG_PMU, NULL, NULL, MXML_DESCEND)) {
const char *const pmncName = mxmlElementGetAttr(node, ATTR_PMNC_NAME);
const char *const cpuidStr = mxmlElementGetAttr(node, ATTR_CPUID);
- const int cpuid = strtol(cpuidStr, NULL, 0);
+ int cpuid;
+ if (!stringToInt(&cpuid, cpuidStr, 0)) {
+ logg.logError("The cpuid for '%s' in pmu XML is not an integer", pmncName);
+ handleException();
+ }
const char *const coreName = mxmlElementGetAttr(node, ATTR_CORE_NAME);
const char *const dtName = mxmlElementGetAttr(node, ATTR_DT_NAME);
const char *const pmncCountersStr = mxmlElementGetAttr(node, ATTR_PMNC_COUNTERS);
- const int pmncCounters = strtol(pmncCountersStr, NULL, 0);
+ int pmncCounters;
+ if (!stringToInt(&pmncCounters, pmncCountersStr, 0)) {
+ logg.logError("The pmnc_counters for '%s' in pmu XML is not an integer", pmncName);
+ handleException();
+ }
if (pmncName == NULL || cpuid == 0 || coreName == NULL || pmncCounters == 0) {
logg.logError("A pmu from the pmu XML is missing one or more of the required attributes (%s, %s, %s and %s)", ATTR_PMNC_NAME, ATTR_CPUID, ATTR_CORE_NAME, ATTR_PMNC_COUNTERS);
handleException();
@@ -80,7 +90,11 @@ void PmuXML::parse(const char *const xml) {
const char *const pmncName = mxmlElementGetAttr(node, ATTR_PMNC_NAME);
const char *const coreName = mxmlElementGetAttr(node, ATTR_CORE_NAME);
const char *const pmncCountersStr = mxmlElementGetAttr(node, ATTR_PMNC_COUNTERS);
- const int pmncCounters = strtol(pmncCountersStr, NULL, 0);
+ int pmncCounters;
+ if (!stringToInt(&pmncCounters, pmncCountersStr, 0)) {
+ logg.logError("The pmnc_counters for '%s' in pmu XML is not an integer", pmncName);
+ handleException();
+ }
const char *const hasCyclesCounterStr = mxmlElementGetAttr(node, ATTR_HAS_CYCLES_COUNTER);
const bool hasCyclesCounter = stringToBool(hasCyclesCounterStr, true);
if (pmncName == NULL || coreName == NULL || pmncCounters == 0) {
@@ -149,4 +163,27 @@ void PmuXML::writeToKernel() {
if (!foundCpu) {
logCpuNotFound();
}
+
+ {
+ DIR *dir = opendir("/dev/gator/clusters");
+
+ struct dirent *dirent;
+ while ((dirent = readdir(dir)) != NULL) {
+ GatorCpu *gatorCpu = GatorCpu::find(dirent->d_name);
+ if (gatorCpu != NULL) {
+ snprintf(buf, sizeof(buf), "/dev/gator/clusters/%s", dirent->d_name);
+ int clusterId;
+ if (DriverSource::readIntDriver(buf, &clusterId)) {
+ logg.logError("Unable to read cluster id");
+ handleException();
+ }
+ gSessionData.mSharedData->mClusters[clusterId] = gatorCpu;
+ gSessionData.mSharedData->mClusterCount = max(gSessionData.mSharedData->mClusterCount, clusterId + 1);
+ }
+ }
+
+ closedir(dir);
+
+ gSessionData.updateClusterIds();
+ }
}
diff --git a/tools/gator/daemon/PmuXML.h b/tools/gator/daemon/PmuXML.h
index a2d6222e7651..173db9c7ecae 100644
--- a/tools/gator/daemon/PmuXML.h
+++ b/tools/gator/daemon/PmuXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Proc.cpp b/tools/gator/daemon/Proc.cpp
index a9f9a51442cc..1aeefc63cb1b 100644
--- a/tools/gator/daemon/Proc.cpp
+++ b/tools/gator/daemon/Proc.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
@@ -19,6 +19,7 @@
#include "Buffer.h"
#include "DynBuf.h"
#include "Logging.h"
+#include "OlyUtility.h"
#include "SessionData.h"
struct ProcStat {
@@ -117,9 +118,8 @@ static bool readProcTask(const uint64_t currTime, Buffer *const buffer, const in
struct dirent *dirent;
while ((dirent = readdir(task)) != NULL) {
- char *endptr;
- const int tid = strtol(dirent->d_name, &endptr, 10);
- if (*endptr != '\0') {
+ int tid;
+ if (!stringToInt(&tid, dirent->d_name, 10)) {
// Ignore task items that are not integers like ., etc...
continue;
}
@@ -162,9 +162,8 @@ bool readProcSysDependencies(const uint64_t currTime, Buffer *const buffer, DynB
struct dirent *dirent;
while ((dirent = readdir(proc)) != NULL) {
- char *endptr;
- const int pid = strtol(dirent->d_name, &endptr, 10);
- if (*endptr != '\0') {
+ int pid;
+ if (!stringToInt(&pid, dirent->d_name, 10)) {
// Ignore proc items that are not integers like ., cpuinfo, etc...
continue;
}
@@ -221,9 +220,8 @@ bool readProcMaps(const uint64_t currTime, Buffer *const buffer, DynBuf *const p
struct dirent *dirent;
while ((dirent = readdir(proc)) != NULL) {
- char *endptr;
- const int pid = strtol(dirent->d_name, &endptr, 10);
- if (*endptr != '\0') {
+ int pid;
+ if (!stringToInt(&pid, dirent->d_name, 10)) {
// Ignore proc items that are not integers like ., cpuinfo, etc...
continue;
}
diff --git a/tools/gator/daemon/Proc.h b/tools/gator/daemon/Proc.h
index e1c2968e01bc..c7e3e7a52bf1 100644
--- a/tools/gator/daemon/Proc.h
+++ b/tools/gator/daemon/Proc.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/Sender.cpp b/tools/gator/daemon/Sender.cpp
index 951eb74c087c..c5593d6e00e0 100644
--- a/tools/gator/daemon/Sender.cpp
+++ b/tools/gator/daemon/Sender.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Sender.h b/tools/gator/daemon/Sender.h
index 010a2223e72c..7404287dd9b3 100644
--- a/tools/gator/daemon/Sender.h
+++ b/tools/gator/daemon/Sender.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/SessionData.cpp b/tools/gator/daemon/SessionData.cpp
index 8f61b096b00a..c190e3aa1c83 100644
--- a/tools/gator/daemon/SessionData.cpp
+++ b/tools/gator/daemon/SessionData.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -8,6 +8,7 @@
#include "SessionData.h"
+#include <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
@@ -20,6 +21,7 @@
#include "Logging.h"
#include "MemInfoDriver.h"
#include "NetDriver.h"
+#include "OlyUtility.h"
#include "SessionXML.h"
#define CORE_NAME_UNKNOWN "unknown"
@@ -31,7 +33,7 @@ SessionData gSessionData;
GatorCpu *GatorCpu::mHead;
-GatorCpu::GatorCpu(const char *const coreName, const char *const pmncName, const char *const dtName, const int cpuid, const int pmncCounters) : mNext(mHead), mCoreName(coreName), mPmncName(pmncName), mDtName(dtName), mCpuid(cpuid), mPmncCounters(pmncCounters) {
+GatorCpu::GatorCpu(const char *const coreName, const char *const pmncName, const char *const dtName, const int cpuid, const int pmncCounters) : mNext(mHead), mCoreName(coreName), mPmncName(pmncName), mDtName(dtName), mCpuid(cpuid), mPmncCounters(pmncCounters), mType(-1) {
mHead = this;
}
@@ -94,6 +96,38 @@ SessionData::SessionData() {
SessionData::~SessionData() {
}
+static long getMaxCoreNum() {
+ DIR *dir = opendir("/sys/devices/system/cpu");
+ if (dir == NULL) {
+ logg.logError("Unable to determine the number of cores on the target, opendir failed");
+ handleException();
+ }
+
+ long maxCoreNum = -1;
+ struct dirent *dirent;
+ while ((dirent = readdir(dir)) != NULL) {
+ if (strncmp(dirent->d_name, "cpu", 3) == 0) {
+ long coreNum;
+ if (stringToLong(&coreNum, dirent->d_name + 3, 10) && (coreNum >= maxCoreNum)) {
+ maxCoreNum = coreNum + 1;
+ }
+ }
+ }
+ closedir(dir);
+
+ if (maxCoreNum < 1) {
+ logg.logError("Unable to determine the number of cores on the target, no cpu# directories found");
+ handleException();
+ }
+
+ if (maxCoreNum >= NR_CPUS) {
+ logg.logError("Too many cores on the target, please increase NR_CPUS in Config.h");
+ handleException();
+ }
+
+ return maxCoreNum;
+}
+
// Needed to use placement new
inline void *operator new(size_t, void *ptr) { return ptr; }
@@ -138,9 +172,13 @@ void SessionData::initialize() {
mMonotonicStarted = -1;
mBacktraceDepth = 0;
mTotalBufferSize = 0;
- // sysconf(_SC_NPROCESSORS_CONF) is unreliable on 2.6 Android, get the value from the kernel module
- mCores = 1;
- mPageSize = 0;
+ mCores = static_cast<int>(getMaxCoreNum());
+ long l = sysconf(_SC_PAGE_SIZE);
+ if (l < 0) {
+ logg.logError("Unable to obtain the page size");
+ handleException();
+ }
+ mPageSize = static_cast<int>(l);
mAnnotateStart = -1;
}
@@ -206,20 +244,25 @@ void SessionData::readModel() {
fclose(fh);
}
-static void setImplementer(int &cpuId, const int implementer) {
- if (cpuId == -1) {
- cpuId = 0;
+static void setImplementer(int *const cpuId, const int implementer) {
+ if (*cpuId == -1) {
+ *cpuId = 0;
}
- cpuId |= implementer << 12;
+ *cpuId |= implementer << 12;
}
-static void setPart(int &cpuId, const int part) {
- if (cpuId == -1) {
- cpuId = 0;
+static void setPart(int *const cpuId, const int part) {
+ if (*cpuId == -1) {
+ *cpuId = 0;
}
- cpuId |= part;
+ *cpuId |= part;
}
+static const char HARDWARE[] = "Hardware";
+static const char CPU_IMPLEMENTER[] = "CPU implementer";
+static const char CPU_PART[] = "CPU part";
+static const char PROCESSOR[] = "processor";
+
void SessionData::readCpuInfo() {
char temp[256]; // arbitrarily large amount
mMaxCpuId = -1;
@@ -233,6 +276,7 @@ void SessionData::readCpuInfo() {
bool foundCoreName = (strcmp(mCoreName, CORE_NAME_UNKNOWN) != 0);
int processor = -1;
+ bool foundProcessorInSection = false;
while (fgets(temp, sizeof(temp), f)) {
const size_t len = strlen(temp);
@@ -246,13 +290,14 @@ void SessionData::readCpuInfo() {
if (len == 1) {
// New section, clear the processor. Streamline will not know the cpus if the pre Linux 3.8 format of cpuinfo is encountered but also that no incorrect information will be transmitted.
processor = -1;
+ foundProcessorInSection = false;
continue;
}
- const bool foundHardware = !foundCoreName && strstr(temp, "Hardware") != 0;
- const bool foundCPUImplementer = strstr(temp, "CPU implementer") != 0;
- const bool foundCPUPart = strstr(temp, "CPU part") != 0;
- const bool foundProcessor = strstr(temp, "processor") != 0;
+ const bool foundHardware = !foundCoreName && strncmp(temp, HARDWARE, sizeof(HARDWARE) - 1) == 0;
+ const bool foundCPUImplementer = strncmp(temp, CPU_IMPLEMENTER, sizeof(CPU_IMPLEMENTER) - 1) == 0;
+ const bool foundCPUPart = strncmp(temp, CPU_PART, sizeof(CPU_PART) - 1) == 0;
+ const bool foundProcessor = strncmp(temp, PROCESSOR, sizeof(PROCESSOR) - 1) == 0;
if (foundHardware || foundCPUImplementer || foundCPUPart || foundProcessor) {
char* position = strchr(temp, ':');
if (position == NULL || (unsigned int)(position - temp) + 2 >= strlen(temp)) {
@@ -269,39 +314,43 @@ void SessionData::readCpuInfo() {
}
if (foundCPUImplementer) {
- const int implementer = strtol(position, NULL, 0);
- if (processor >= NR_CPUS) {
+ int implementer;
+ if (!stringToInt(&implementer, position, 0)) {
+ // Do nothing
+ } else if (processor >= NR_CPUS) {
logg.logMessage("Too many processors, please increase NR_CPUS");
} else if (processor >= 0) {
- setImplementer(mSharedData->mCpuIds[processor], implementer);
+ setImplementer(&mSharedData->mCpuIds[processor], implementer);
} else {
- setImplementer(mMaxCpuId, implementer);
+ setImplementer(&mMaxCpuId, implementer);
}
}
if (foundCPUPart) {
- const int cpuId = strtol(position, NULL, 0);
- if (processor >= NR_CPUS) {
+ int cpuId;
+ if (!stringToInt(&cpuId, position, 0)) {
+ // Do nothing
+ } else if (processor >= NR_CPUS) {
logg.logMessage("Too many processors, please increase NR_CPUS");
} else if (processor >= 0) {
- setPart(mSharedData->mCpuIds[processor], cpuId);
+ setPart(&mSharedData->mCpuIds[processor], cpuId);
} else {
- setPart(mMaxCpuId, cpuId);
+ setPart(&mMaxCpuId, cpuId);
}
}
if (foundProcessor) {
- processor = strtol(position, NULL, 0);
+ if (foundProcessorInSection) {
+ // Found a second processor in this section, ignore them all
+ processor = -1;
+ } else if (stringToInt(&processor, position, 0)) {
+ foundProcessorInSection = true;
+ }
}
}
}
- // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
- for (int i = 0; i < NR_CPUS; ++i) {
- if (mSharedData->mCpuIds[i] > mMaxCpuId) {
- mMaxCpuId = mSharedData->mCpuIds[i];
- }
- }
+ updateClusterIds();
if (!foundCoreName) {
logg.logMessage("Could not determine core name from /proc/cpuinfo\n"
@@ -310,6 +359,39 @@ void SessionData::readCpuInfo() {
fclose(f);
}
+static int clusterCompare(const void *a, const void *b) {
+ const GatorCpu *const *const lhs = (const GatorCpu **)a;
+ const GatorCpu *const *const rhs = (const GatorCpu **)b;
+
+ return (*rhs)->getCpuid() - (*lhs)->getCpuid();
+}
+
+void SessionData::updateClusterIds() {
+ qsort(&mSharedData->mClusters, mSharedData->mClusterCount, sizeof(*mSharedData->mClusters), clusterCompare);
+ mSharedData->mClustersAccurate = true;
+ for (int i = 0; i < NR_CPUS; ++i) {
+ // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
+ if (mSharedData->mCpuIds[i] > mMaxCpuId) {
+ mMaxCpuId = mSharedData->mCpuIds[i];
+ }
+
+ int clusterId = -1;
+ for (int j = 0; j < min(mSharedData->mClusterCount, ARRAY_LENGTH(mSharedData->mClusters)); ++j) {
+ const int cpuId = mSharedData->mClusters[j]->getCpuid();
+ if (mSharedData->mCpuIds[i] == cpuId) {
+ clusterId = j;
+ }
+ }
+ if (i < mCores && clusterId == -1) {
+ // No corresponding cluster found for this CPU, most likely this is a big LITTLE system without multi-PMU support
+ mSharedData->mClusterIds[i] = 0;
+ mSharedData->mClustersAccurate = false;
+ } else {
+ mSharedData->mClusterIds[i] = clusterId;
+ }
+ }
+}
+
uint64_t getTime() {
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
diff --git a/tools/gator/daemon/SessionData.h b/tools/gator/daemon/SessionData.h
index 38e8163d1f64..bc8b7d7a9b97 100644
--- a/tools/gator/daemon/SessionData.h
+++ b/tools/gator/daemon/SessionData.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -23,7 +23,7 @@
#include "PerfDriver.h"
#include "TtraceDriver.h"
-#define PROTOCOL_VERSION 231
+#define PROTOCOL_VERSION 240
// Differentiates development versions (timestamp) from release versions
#define PROTOCOL_DEV 10000000
@@ -71,6 +71,14 @@ public:
return mPmncCounters;
}
+ void setType(int type) {
+ mType = type;
+ }
+
+ int getType() const {
+ return mType;
+ }
+
static GatorCpu *find(const char *const name);
static GatorCpu *find(const int cpuid);
@@ -83,6 +91,7 @@ private:
const char *const mDtName;
const int mCpuid;
const int mPmncCounters;
+ int mType;
};
class UncorePmu {
@@ -129,10 +138,14 @@ public:
SharedData();
int mCpuIds[NR_CPUS];
+ int mClusterIds[NR_CPUS];
+ const GatorCpu *mClusters[CLUSTER_COUNT];
+ int mClusterCount;
size_t mMaliUtgardCountersSize;
char mMaliUtgardCounters[1<<12];
size_t mMaliMidgardCountersSize;
char mMaliMidgardCounters[1<<13];
+ bool mClustersAccurate;
private:
// Intentionally unimplemented
@@ -151,6 +164,7 @@ public:
void parseSessionXML(char* xmlString);
void readModel();
void readCpuInfo();
+ void updateClusterIds();
SharedData *mSharedData;
@@ -227,4 +241,8 @@ void logCpuNotFound();
bool getLinuxVersion(int version[3]);
+const char *mxmlWhitespaceCB(mxml_node_t *node, int where);
+
+void copyMxmlElementAttrs(mxml_node_t *dest, mxml_node_t *src);
+
#endif // SESSION_DATA_H
diff --git a/tools/gator/daemon/SessionXML.cpp b/tools/gator/daemon/SessionXML.cpp
index 742f0c49cc86..e0eddd6fd581 100644
--- a/tools/gator/daemon/SessionXML.cpp
+++ b/tools/gator/daemon/SessionXML.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -62,7 +62,10 @@ void SessionXML::parse() {
void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
int version = 0;
- if (mxmlElementGetAttr(node, ATTR_VERSION)) version = strtol(mxmlElementGetAttr(node, ATTR_VERSION), NULL, 10);
+ if (mxmlElementGetAttr(node, ATTR_VERSION) && !stringToInt(&version, mxmlElementGetAttr(node, ATTR_VERSION), 10)) {
+ logg.logError("Invalid session.xml version must be an integer");
+ handleException();
+ }
if (version != 1) {
logg.logError("Invalid session.xml version: %d", version);
handleException();
@@ -83,9 +86,15 @@ void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
// integers/bools
parameters.call_stack_unwinding = stringToBool(mxmlElementGetAttr(node, ATTR_CALL_STACK_UNWINDING), false);
- if (mxmlElementGetAttr(node, ATTR_DURATION)) gSessionData.mDuration = strtol(mxmlElementGetAttr(node, ATTR_DURATION), NULL, 10);
+ if (mxmlElementGetAttr(node, ATTR_DURATION) && !stringToInt(&gSessionData.mDuration, mxmlElementGetAttr(node, ATTR_DURATION), 10)) {
+ logg.logError("Invalid session.xml duration must be an integer");
+ handleException();
+ }
gSessionData.mFtraceRaw = stringToBool(mxmlElementGetAttr(node, USE_EFFICIENT_FTRACE), false);
- if (mxmlElementGetAttr(node, ATTR_LIVE_RATE)) parameters.live_rate = strtol(mxmlElementGetAttr(node, ATTR_LIVE_RATE), NULL, 10);
+ if (mxmlElementGetAttr(node, ATTR_LIVE_RATE) && !stringToInt(&parameters.live_rate, mxmlElementGetAttr(node, ATTR_LIVE_RATE), 10)) {
+ logg.logError("Invalid session.xml live_rate must be an integer");
+ handleException();
+ }
// parse subtags
node = mxmlGetFirstChild(node);
diff --git a/tools/gator/daemon/SessionXML.h b/tools/gator/daemon/SessionXML.h
index 2ba276a38021..423bb62ca9cf 100644
--- a/tools/gator/daemon/SessionXML.h
+++ b/tools/gator/daemon/SessionXML.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Source.cpp b/tools/gator/daemon/Source.cpp
index 3084bcba5414..15122deb6ecf 100644
--- a/tools/gator/daemon/Source.cpp
+++ b/tools/gator/daemon/Source.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/Source.h b/tools/gator/daemon/Source.h
index b9369be5198b..954d3acf08f0 100644
--- a/tools/gator/daemon/Source.h
+++ b/tools/gator/daemon/Source.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/StreamlineSetup.cpp b/tools/gator/daemon/StreamlineSetup.cpp
index f00d7f18596a..303e95994d9c 100644
--- a/tools/gator/daemon/StreamlineSetup.cpp
+++ b/tools/gator/daemon/StreamlineSetup.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2011-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2016. 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
@@ -216,9 +216,8 @@ void StreamlineSetup::sendConfiguration() {
void StreamlineSetup::sendDefaults() {
// Send the config built into the binary
- const char* xml;
- unsigned int size;
- ConfigurationXML::getDefaultConfigurationXml(xml, size);
+ char* xml = ConfigurationXML::getDefaultConfigurationXml();
+ size_t size = strlen(xml);
// Artificial size restriction
if (size > 1024*1024) {
@@ -227,6 +226,7 @@ void StreamlineSetup::sendDefaults() {
}
sendData(xml, size, RESPONSE_XML);
+ free(xml);
}
void StreamlineSetup::sendCounters() {
@@ -240,19 +240,34 @@ void StreamlineSetup::sendCounters() {
count += driver->writeCounters(counters);
}
- mxml_node_t *setup = mxmlNewElement(counters, "setup_warnings");
- mxmlNewText(setup, 0, logg.getSetup());
-
if (count == 0) {
logg.logError("No counters found, this could be because /dev/gator/events can not be read or because perf is not working correctly");
handleException();
}
+ mxml_node_t *setup = mxmlNewElement(counters, "setup_warnings");
+ mxmlNewText(setup, 0, logg.getSetup());
+
+ if (gSessionData.mSharedData->mClustersAccurate) {
+ for (int cluster = 0; cluster < gSessionData.mSharedData->mClusterCount; ++cluster) {
+ mxml_node_t *node = mxmlNewElement(counters, "cluster");
+ mxmlElementSetAttrf(node, "id", "%i", cluster);
+ mxmlElementSetAttr(node, "name", gSessionData.mSharedData->mClusters[cluster]->getPmncName());
+ }
+ for (int cpu = 0; cpu < gSessionData.mCores; ++cpu) {
+ if (gSessionData.mSharedData->mClusterIds[cpu] >= 0) {
+ mxml_node_t *node = mxmlNewElement(counters, "cpu");
+ mxmlElementSetAttrf(node, "id", "%i", cpu);
+ mxmlElementSetAttrf(node, "cluster", "%i", gSessionData.mSharedData->mClusterIds[cpu]);
+ }
+ }
+ }
+
char* string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
- sendString(string, RESPONSE_XML);
+ mxmlDelete(xml);
+ sendString(string, RESPONSE_XML);
free(string);
- mxmlDelete(xml);
}
void StreamlineSetup::writeConfiguration(char* xml) {
diff --git a/tools/gator/daemon/StreamlineSetup.h b/tools/gator/daemon/StreamlineSetup.h
index d8b162606436..12f923e65050 100644
--- a/tools/gator/daemon/StreamlineSetup.h
+++ b/tools/gator/daemon/StreamlineSetup.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/TtraceDriver.cpp b/tools/gator/daemon/TtraceDriver.cpp
index e1ce83313765..db06a9d69f6b 100644
--- a/tools/gator/daemon/TtraceDriver.cpp
+++ b/tools/gator/daemon/TtraceDriver.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2014-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2014-2016. 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
@@ -48,11 +48,11 @@ TtraceDriver::~TtraceDriver() {
void TtraceDriver::readEvents(mxml_node_t *const xml) {
if (access("/etc/tizen-release", R_OK) != 0) {
// Reduce warning noise
- //logg.logSetup("Ttrace Disabled\n/etc/tizen-release is not found, this is not a Tizen target");
+ //logg.logSetup("Ttrace is disabled\n/etc/tizen-release is not found, this is not a Tizen target");
return;
}
if (!gSessionData.mFtraceDriver.isSupported()) {
- logg.logSetup("Ttrace Disabled\nftrace support is required");
+ logg.logSetup("Ttrace is disabled\nSupport for ftrace required");
return;
}
@@ -73,12 +73,17 @@ void TtraceDriver::readEvents(mxml_node_t *const xml) {
continue;
}
- const char *flag = mxmlElementGetAttr(node, "flag");
- if (flag == NULL) {
+ const char *flagStr = mxmlElementGetAttr(node, "flag");
+ if (flagStr == NULL) {
logg.logError("The ttrace counter %s is missing the required flag attribute", counter);
handleException();
}
- setCounters(new TtraceCounter(getCounters(), strdup(counter), strtol(flag, NULL, 16)));
+ int flag;
+ if (!stringToInt(&flag, flagStr, 16)) {
+ logg.logError("The flag attribute of the ttrace counter %s is not a hex integer", counter);
+ handleException();
+ }
+ setCounters(new TtraceCounter(getCounters(), strdup(counter), flag));
}
}
diff --git a/tools/gator/daemon/TtraceDriver.h b/tools/gator/daemon/TtraceDriver.h
index 86a0630f14c4..fd6e45677ca3 100644
--- a/tools/gator/daemon/TtraceDriver.h
+++ b/tools/gator/daemon/TtraceDriver.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2015. All rights reserved.
+ * Copyright (C) ARM Limited 2015-2016. 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
diff --git a/tools/gator/daemon/UEvent.cpp b/tools/gator/daemon/UEvent.cpp
index 3b0447a2257b..11ad34f84a88 100644
--- a/tools/gator/daemon/UEvent.cpp
+++ b/tools/gator/daemon/UEvent.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/UEvent.h b/tools/gator/daemon/UEvent.h
index 4c00f6cff112..c819a9fe29d8 100644
--- a/tools/gator/daemon/UEvent.h
+++ b/tools/gator/daemon/UEvent.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2013-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2016. 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
diff --git a/tools/gator/daemon/UserSpaceSource.cpp b/tools/gator/daemon/UserSpaceSource.cpp
index 6b9565b802be..b9dd91884130 100644
--- a/tools/gator/daemon/UserSpaceSource.cpp
+++ b/tools/gator/daemon/UserSpaceSource.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/UserSpaceSource.h b/tools/gator/daemon/UserSpaceSource.h
index 0038dcb4c3d5..01c092e62e1b 100644
--- a/tools/gator/daemon/UserSpaceSource.h
+++ b/tools/gator/daemon/UserSpaceSource.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/c++.cpp b/tools/gator/daemon/c++.cpp
index caf6f1efdcde..923bf05227bd 100644
--- a/tools/gator/daemon/c++.cpp
+++ b/tools/gator/daemon/c++.cpp
@@ -1,7 +1,7 @@
/**
* Minimal set of C++ functions so that libstdc++ is not required
*
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/common.mk b/tools/gator/daemon/common.mk
index 344abd27fc83..430b988f8e4d 100644
--- a/tools/gator/daemon/common.mk
+++ b/tools/gator/daemon/common.mk
@@ -6,7 +6,7 @@
# -std=c++0x is the planned new c++ standard
# -std=c++98 is the 1998 c++ standard
CPPFLAGS += -O3 -Wall -fno-exceptions -pthread -MD -DETCDIR=\"/etc\" -Ilibsensors
-CXXFLAGS += -fno-rtti -Wextra -Wshadow # -Weffc++
+CXXFLAGS += -fno-rtti -Wextra -Wshadow -Wpointer-arith -Wundef # -Weffc++ -Wmissing-declarations
ifeq ($(WERROR),1)
CPPFLAGS += -Werror
endif
@@ -17,10 +17,27 @@ TARGET = gatord
C_SRC = $(wildcard mxml/*.c) $(wildcard libsensors/*.c)
CXX_SRC = $(wildcard *.cpp)
+ifeq ($(V),1)
+ Q =
+ ECHO_HOSTCC =
+ ECHO_GEN =
+ ECHO_CC =
+ ECHO_CXX =
+ ECHO_CCLD =
+else
+ Q = @
+ ECHO_HOSTCC = @echo " HOSTCC " $@
+ ECHO_GEN = @echo " GEN " $@
+ ECHO_CC = @echo " CC " $@
+ ECHO_CXX = @echo " CXX " $@
+ ECHO_CCLD = @echo " CCLD " $@
+endif
+
all: $(TARGET)
events.xml: events_header.xml $(wildcard events-*.xml) events_footer.xml
- cat $^ > $@
+ $(ECHO_GEN)
+ $(Q)cat $^ > $@
include $(wildcard *.d)
include $(wildcard mxml/*.d)
@@ -35,23 +52,29 @@ libsensors/conf-lex.c: ;
libsensors/conf-parse.c: ;
%_xml.h: %.xml escape
- ./escape $< > $@
+ $(ECHO_GEN)
+ $(Q)./escape $< > $@
%.o: %.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+ $(ECHO_CC)
+ $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
%.o: %.cpp
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
+ $(ECHO_CXX)
+ $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
SrcMd5.cpp: $(wildcard *.cpp *.h mxml/*.c mxml/*.h libsensors/*.c libsensors/*.h)
- echo 'extern const char *const gSrcMd5 = "'`ls $^ | grep -Ev '^(.*_xml\.h|$@)$$' | LC_ALL=C sort | xargs cat | md5sum | cut -b 1-32`'";' > $@
+ $(ECHO_GEN)
+ $(Q)echo 'extern const char *const gSrcMd5 = "'`ls $^ | grep -Ev '^(.*_xml\.h|$@)$$' | LC_ALL=C sort | xargs cat | md5sum | cut -b 1-32`'";' > $@
$(TARGET): $(CXX_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o) SrcMd5.o
- $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+ $(ECHO_CCLD)
+ $(Q)$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
# Intentionally ignore CC as a native binary is required
escape: escape.c
- gcc $^ -o $@
+ $(ECHO_HOSTCC)
+ $(Q)gcc $^ -o $@
clean:
rm -f *.d *.o mxml/*.d mxml/*.o libsensors/*.d libsensors/*.o $(TARGET) escape events.xml *_xml.h SrcMd5.cpp
diff --git a/tools/gator/daemon/defaults.xml b/tools/gator/daemon/defaults.xml
index 5d0d62005e0b..ebbb6bd397eb 100644
--- a/tools/gator/daemon/defaults.xml
+++ b/tools/gator/daemon/defaults.xml
@@ -34,6 +34,11 @@
<configuration counter="ARMv7_Cortex_A17_cnt1" event="0x16"/>
<configuration counter="ARMv7_Cortex_A17_cnt2" event="0x10"/>
<configuration counter="ARMv7_Cortex_A17_cnt3" event="0x19"/>
+ <configuration counter="ARMv8_Cortex_A32_ccnt" event="0x11"/>
+ <configuration counter="ARMv8_Cortex_A32_cnt0" event="0x8"/>
+ <configuration counter="ARMv8_Cortex_A32_cnt1" event="0x16"/>
+ <configuration counter="ARMv8_Cortex_A32_cnt2" event="0x10"/>
+ <configuration counter="ARMv8_Cortex_A32_cnt3" event="0x19"/>
<configuration counter="ARMv8_Cortex_A35_ccnt" event="0x11"/>
<configuration counter="ARMv8_Cortex_A35_cnt0" event="0x8"/>
<configuration counter="ARMv8_Cortex_A35_cnt1" event="0x16"/>
@@ -73,9 +78,9 @@
<configuration counter="Linux_meminfo_memused"/>
<configuration counter="Linux_meminfo_memused2"/>
<configuration counter="Linux_meminfo_memfree"/>
- <configuration counter="Linux_power_cpu_freq"/>
- <configuration counter="Linux_cpu_system"/>
- <configuration counter="Linux_cpu_user"/>
+ <configuration counter="${cluster}_freq"/>
+ <configuration counter="${cluster}_system"/>
+ <configuration counter="${cluster}_user"/>
<configuration counter="ARM_Mali-4xx_fragment"/>
<configuration counter="ARM_Mali-4xx_vertex"/>
<configuration counter="ARM_Mali-Midgard_fragment" cores="1"/>
diff --git a/tools/gator/daemon/escape.c b/tools/gator/daemon/escape.c
index 99f434848cb3..f73d960a3748 100644
--- a/tools/gator/daemon/escape.c
+++ b/tools/gator/daemon/escape.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
diff --git a/tools/gator/daemon/events-Cortex-A32.xml b/tools/gator/daemon/events-Cortex-A32.xml
new file mode 100644
index 000000000000..1ef8ad373c8b
--- /dev/null
+++ b/tools/gator/daemon/events-Cortex-A32.xml
@@ -0,0 +1,63 @@
+ <counter_set name="ARMv8_Cortex_A32_cnt" count="6"/>
+ <category name="Cortex-A32" counter_set="ARMv8_Cortex_A32_cnt" per_cpu="yes" supports_event_based_sampling="yes">
+ <event counter="ARMv8_Cortex_A32_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
+ <event event="0x00" title="Software" name="Increment" description="Software increment. The register is incremented only on writes to the Software Increment Register."/>
+ <event event="0x01" title="Cache" name="Instruction refill" description="L1 Instruction cache refill"/>
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="L1 Instruction TLB refill"/>
+ <event event="0x03" title="Cache" name="Data refill" description="L1 Data cache refill"/>
+ <event event="0x04" title="Cache" name="Data access" description="L1 Data cache access"/>
+ <event event="0x05" title="Cache" name="Data TLB refill" description="L1 Data TLB refill"/>
+ <event event="0x06" title="Instruction" name="Data Read" description="Instruction that is architecturally executed, condition check pass - load"/>
+ <event event="0x07" title="Instruction" name="Memory write" description="Instruction that is architecturally executed, condition check pass - store"/>
+ <event event="0x08" title="Instruction" name="Executed" description="Instruction that is architecturally executed"/>
+ <event event="0x09" title="Exception" name="Taken" description="Exception taken"/>
+ <event event="0x0a" title="Exception" name="Return" description="Exception return"/>
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Change to Context ID retired"/>
+ <event event="0x0c" title="Branch" name="PC change" description="Instruction that is architecturally executed, condition check pass, software change of the PC"/>
+ <event event="0x0d" title="Branch" name="Immediate" description="Instruction that is architecturally executed, immediate branch"/>
+ <event event="0x0e" title="Procedure" name="Return" description="Instruction that is architecturally executed, condition code check pass, procedure return"/>
+ <event event="0x0f" title="Memory" name="Unaligned access" description="Instruction that is architecturally executed, condition check pass, unaligned load or store"/>
+ <event event="0x10" title="Branch" name="Mispredicted" description="Mispredicted or not predicted branch that is speculatively executed"/>
+ <event event="0x12" title="Branch" name="Potential prediction" description="Predictable branch that is speculatively executed"/>
+ <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
+ <event event="0x14" title="Cache" name="L1 inst access" description="L1 Instruction cache access"/>
+ <event event="0x15" title="Cache" name="L1 data write" description="L1 Data cache writeback"/>
+ <event event="0x16" title="Cache" name="L2 data access" description="L2 Data cache access"/>
+ <event event="0x17" title="Cache" name="L2 data refill" description="L2 Data cache refill"/>
+ <event event="0x18" title="Cache" name="L2 data write" description="L2 Data cache write-back"/>
+ <event event="0x19" title="Bus" name="Access" description="Bus access"/>
+ <event event="0x1a" title="Memory" name="Error" description="Local memory error"/>
+ <event event="0x1d" title="Bus" name="Cycle" description="Bus cycle"/>
+ <event event="0x1e" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
+ <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
+ <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
+ <event event="0x7a" title="Branch" name="Indirect" description="Branch that is speculatively executed - Indirect branch"/>
+ <event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/>
+ <event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/>
+ <event event="0xc0" title="Memory" name="External request" description="External memory request"/>
+ <event event="0xc1" title="Memory" name="Non-cacheable ext req" description="Non-cacheable external memory request"/>
+ <event event="0xc2" title="Cache" name="Linefill" description="Linefill because of prefetch"/>
+ <event event="0xc4" title="Cache" name="Allocate mode enter" description="Entering read allocate mode"/>
+ <event event="0xc5" title="Cache" name="Allocate mode" description="Read allocate mode"/>
+ <event event="0xc6" title="Pre-decode" name="error" description="Pre-decode error"/>
+ <event event="0xc7" title="Memory" name="Write stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
+ <event event="0xc8" title="Memory" name="Snoop" description="SCU Snooped data from another core for this core"/>
+ <event event="0xc9" title="Branch" name="Taken" description="Conditional branch that is executed"/>
+ <!--
+ <event event="0xca" title="Branch" name="Mispredicted a" description="Indirect branch that is mispredicted"/>
+ <event event="0xcb" title="Branch" name="Mispredicted b" description="Indirect branch that is mispredicted because of address miscompare"/>
+ <event event="0xcc" title="Branch" name="Mispredicted c" description="Conditional branch that is mispredicted"/>
+ -->
+ <event event="0xd0" title="Cache" name="L1 inst error" description="L1 Instruction Cache (data or tag) memory error"/>
+ <event event="0xd1" title="Cache" name="L1 data error" description="L1 Data Cache (data, tag, or dirty) memory error, correctable or non-correctable"/>
+ <event event="0xd2" title="Cache" name="TLB error" description="TLB memory error"/>
+ <event event="0xe0" title="Stall" name="DPU IP empty" description="Attributable Performance Impact Event. Counts every cycle that the DPU IQ is empty and that is not because of a recent micro-TLB miss, an instruction cache miss or a pre-decode error."/>
+ <event event="0xe1" title="Stall" name="Cache miss" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction cache miss being processed."/>
+ <event event="0xe2" title="Stall" name="TLB miss" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction micro-TLB miss being processed."/>
+ <event event="0xe3" title="Stall" name="Pre-decode error" description="Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is a pre-decode error being processed."/>
+ <event event="0xe4" title="Stall" name="Interlock other" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is not because of an Advanced SIMD or floating-point instruction, and not because of a load/store instruction waiting for data to calculate the address in the AGU. Stall cycles because of a stall in Wr, typically awaiting load data, are excluded."/>
+ <event event="0xe5" title="Stall" name="Interlock address" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of a load/store instruction waiting for data to calculate the address in the AGU. Stall cycles because of a stall in Wr, typically awaiting load data, are excluded."/>
+ <event event="0xe6" title="Stall" name="Interlock SIMD/FPU" description="Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of an Advanced SIMD or floating-point instruction. Stall cycles because of a stall in the Wr stage, typically awaiting load data, are excluded."/>
+ <event event="0xe7" title="Stall" name="Load miss" description="Attributable Performance Impact Event Counts every cycle there is a stall in the Wr stage because of a load miss"/>
+ <event event="0xe8" title="Stall" name="Store" description="Attributable Performance Impact Event. Counts every cycle there is a stall in the Wr stage because of a store."/>
+ </category>
diff --git a/tools/gator/daemon/events-Linux.xml b/tools/gator/daemon/events-Linux.xml
index 1b1a6af87a6f..b9ae4103c97f 100644
--- a/tools/gator/daemon/events-Linux.xml
+++ b/tools/gator/daemon/events-Linux.xml
@@ -1,19 +1,20 @@
<category name="Linux">
- <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="${cluster}_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/>
+ <event counter="${cluster}_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/>
<event counter="Linux_block_rq_wr" title="Disk I/O" name="Write" units="B" description="Disk I/O Bytes Written"/>
<event counter="Linux_block_rq_rd" title="Disk I/O" name="Read" units="B" description="Disk I/O 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" per_cpu="yes" description="Context switch events"/>
+ <event counter="${cluster}_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/>
<event counter="Linux_meminfo_memused" title="Memory" name="Used" class="absolute" units="B" proc="yes" description="Total used memory size. Note: a process' used memory includes shared memory that may be counted more than once (equivalent to RES from top). Kernel threads are not filterable."/>
<event counter="Linux_meminfo_memused2" title="Memory" name="Used" class="absolute" units="B" description="Total used memory size"/>
<event counter="Linux_meminfo_memfree" title="Memory" name="Free" class="absolute" display="minimum" units="B" description="Available memory size"/>
- <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" class="absolute" units="B" description="Memory used by OS disk buffers"/>
- <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" class="absolute" units="Hz" series_composition="overlay" average_cores="yes" description="Frequency setting of the CPU"/>
+ <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" class="absolute" units="B" description="Memory used by OS disk buffers, included in Memory: Used"/>
+ <event counter="Linux_meminfo_cached" title="Memory" name="Cached" class="absolute" units="B" description="Memory used by OS disk cache, included in Memory: Used"/>
+ <event counter="Linux_meminfo_slab" title="Memory" name="Slab" class="absolute" units="B" description="Memory used by the kernel, included in Memory: Used"/>
+ <event counter="${cluster}_freq" title="Clock" name="Frequency" per_cpu="yes" class="absolute" units="Hz" series_composition="overlay" average_cores="yes" description="Frequency setting of the CPU"/>
<event counter="Linux_cpu_wait_contention" title="CPU Contention" name="Wait" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x003c96fb" description="One or more threads are runnable but waiting due to CPU contention"/>
<event counter="Linux_cpu_wait_io" title="CPU I/O" name="Wait" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x00b30000" description="One or more threads are blocked on an I/O resource"/>
- <event counter="Linux_cpu_system" title="CPU Activity" name="System" per_cpu="yes" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x00DF4742" average_cores="yes" description="Linux System activity"/><!-- cores="needs to be dynamically set" -->
- <event counter="Linux_cpu_user" title="CPU Activity" name="User" per_cpu="yes" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x003ADF43" average_cores="yes" description="Linux User activity"/><!-- cores="needs to be dynamically set" -->
- <event counter="Linux_power_cpu" title="CPU Status" name="Activity" class="activity" activity1="Off" activity_color1="0x0000ff00" activity2="WFI" activity_color2="0x000000ff" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" description="CPU Status"/>
+ <event counter="${cluster}_system" title="CPU Activity" name="System" per_cpu="yes" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x00DF4742" average_cores="yes" description="Linux System activity"/>
+ <event counter="${cluster}_user" title="CPU Activity" name="User" per_cpu="yes" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" multiplier="0.0001" color="0x003ADF43" average_cores="yes" description="Linux User activity"/>
</category>
diff --git a/tools/gator/daemon/events-Mali-Midgard.xml b/tools/gator/daemon/events-Mali-Midgard.xml
index 737555b0dbf0..1eadf4a62e30 100644
--- a/tools/gator/daemon/events-Mali-Midgard.xml
+++ b/tools/gator/daemon/events-Mali-Midgard.xml
@@ -22,10 +22,10 @@ power management is disabled during profiling so these counters are not useful a
</category>
-->
<category name="Mali-Midgard MMU Address Space" per_cpu="no">
- <event counter="ARM_Mali-Midgard_MMU_AS_0" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_1" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_2" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
- <event counter="ARM_Mali-Midgard_MMU_AS_3" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_0" class="absolute" display="average" multiplier="0.01" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_1" class="absolute" display="average" multiplier="0.01" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_2" class="absolute" display="average" multiplier="0.01" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
+ <event counter="ARM_Mali-Midgard_MMU_AS_3" class="absolute" display="average" multiplier="0.01" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
</category>
<category name="Mali-Midgard MMU Page Fault" per_cpu="no">
<event counter="ARM_Mali-Midgard_MMU_PAGE_FAULT_0" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 0" description="Reports the number of newly allocated pages after a MMU page fault in address space 0."/>
diff --git a/tools/gator/daemon/main.cpp b/tools/gator/daemon/main.cpp
index 211066fcb10d..00f7aa527a01 100644
--- a/tools/gator/daemon/main.cpp
+++ b/tools/gator/daemon/main.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2015. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2016. 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
@@ -384,11 +384,18 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
cmdline.module = optarg;
break;
case 'p':
- cmdline.port = strtol(optarg, NULL, 10);
+ if (!stringToInt(&cmdline.port, optarg, 10)) {
+ logg.logError("Port must be an integer");
+ handleException();
+ }
if ((cmdline.port == 8082) || (cmdline.port == 8083)) {
logg.logError("Gator can't use port %i, as it already uses ports 8082 and 8083 for annotations. Please select a different port.", cmdline.port);
handleException();
}
+ if (cmdline.port < 1 || cmdline.port > 65535) {
+ logg.logError("Gator can't use port %i, as it is not valid. Please pick a value between 1 and 65535", cmdline.port);
+ handleException();
+ }
break;
case 's':
gSessionData.mSessionXMLPath = optarg;
diff --git a/tools/gator/daemon/pmus.xml b/tools/gator/daemon/pmus.xml
index 77dc9071f192..d637bb8c0ff8 100644
--- a/tools/gator/daemon/pmus.xml
+++ b/tools/gator/daemon/pmus.xml
@@ -25,11 +25,14 @@
<pmu pmnc_name="Krait" cpuid="0x51049" core_name="KraitSIM" pmnc_counters="4"/>
<pmu pmnc_name="Krait" cpuid="0x5104d" core_name="Krait" pmnc_counters="4"/>
<pmu pmnc_name="Krait" cpuid="0x5106f" core_name="Krait S4 Pro" pmnc_counters="4"/>
+ <pmu pmnc_name="ARMv8_Cortex_A32" cpuid="0x41d01" core_name="Cortex-A32" dt_name="arm,cortex-a32" pmnc_counters="6"/>
<pmu pmnc_name="ARMv8_Cortex_A35" cpuid="0x41d04" core_name="Cortex-A35" dt_name="arm,cortex-a35" pmnc_counters="6"/>
<pmu pmnc_name="ARMv8_Cortex_A53" cpuid="0x41d03" core_name="Cortex-A53" dt_name="arm,cortex-a53" pmnc_counters="6"/>
<pmu pmnc_name="ARMv8_Cortex_A57" cpuid="0x41d07" core_name="Cortex-A57" dt_name="arm,cortex-a57" pmnc_counters="6"/>
<pmu pmnc_name="ARMv8_Cortex_A72" cpuid="0x41d08" core_name="Cortex-A72" dt_name="arm,cortex-a72" pmnc_counters="6"/>
<pmu pmnc_name="ARMv8_Exynos_M1" cpuid="0x53001" core_name="Exynos-M1" pmnc_counters="6"/>
+ <!-- This is a guess, but at least the CPU will be recognized -->
+ <pmu pmnc_name="ARMv8_NVIDIA_Denver" cpuid="0x4e000" core_name="Nvidia-Denver" pmnc_counters="6"/>
<uncore_pmu pmnc_name="CCI_400" core_name="CCI_400" pmnc_counters="4"/>
<uncore_pmu pmnc_name="CCI_400_r1" core_name="CCI_400_r1" pmnc_counters="4"/>