aboutsummaryrefslogtreecommitdiff
path: root/daemon/Child.cpp
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2014-10-22 12:00:00 -0700
committerDrew Richardson <drew.richardson@arm.com>2014-12-19 15:59:12 -0800
commitecc3d86ea62f7be7defa303d1d14b8506ec63e75 (patch)
tree4a0c3fb31869e2eca869f3eb2d35c6d1391ecd68 /daemon/Child.cpp
parent6a98fbff8b9f8a23045efdea51784b479cefac7f (diff)
gator: Version 5.205.20
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
Diffstat (limited to 'daemon/Child.cpp')
-rw-r--r--daemon/Child.cpp82
1 files changed, 64 insertions, 18 deletions
diff --git a/daemon/Child.cpp b/daemon/Child.cpp
index 1901ecc..6b5bbb3 100644
--- a/daemon/Child.cpp
+++ b/daemon/Child.cpp
@@ -14,25 +14,28 @@
#include <unistd.h>
#include <sys/prctl.h>
-#include "Logging.h"
#include "CapturedXML.h"
-#include "SessionData.h"
-#include "LocalCapture.h"
-#include "Sender.h"
-#include "OlyUtility.h"
-#include "OlySocket.h"
-#include "StreamlineSetup.h"
+#include "Command.h"
#include "ConfigurationXML.h"
#include "Driver.h"
-#include "PerfSource.h"
#include "DriverSource.h"
#include "ExternalSource.h"
+#include "FtraceSource.h"
+#include "LocalCapture.h"
+#include "Logging.h"
+#include "OlySocket.h"
+#include "OlyUtility.h"
+#include "PerfSource.h"
+#include "Sender.h"
+#include "SessionData.h"
+#include "StreamlineSetup.h"
#include "UserSpaceSource.h"
static sem_t haltPipeline, senderThreadStarted, startProfile, senderSem; // Shared by Child and spawned threads
static Source *primarySource = NULL;
static Source *externalSource = NULL;
static Source *userSpaceSource = NULL;
+static Source *ftraceSource = NULL;
static Sender* sender = NULL; // Shared by Child.cpp and spawned threads
Child* child = NULL; // shared by Child.cpp and main.cpp
@@ -149,7 +152,8 @@ static void *senderThread(void *) {
while (!primarySource->isDone() ||
!externalSource->isDone() ||
- (userSpaceSource != NULL && !userSpaceSource->isDone())) {
+ (userSpaceSource != NULL && !userSpaceSource->isDone()) ||
+ (ftraceSource != NULL && !ftraceSource->isDone())) {
sem_wait(&senderSem);
primarySource->write(sender);
@@ -157,6 +161,9 @@ static void *senderThread(void *) {
if (userSpaceSource != NULL) {
userSpaceSource->write(sender);
}
+ if (ftraceSource != NULL) {
+ ftraceSource->write(sender);
+ }
}
// write end-of-capture sequence
@@ -206,6 +213,9 @@ void Child::endSession() {
if (userSpaceSource != NULL) {
userSpaceSource->interrupt();
}
+ if (ftraceSource != NULL) {
+ ftraceSource->interrupt();
+ }
sem_post(&haltPipeline);
}
@@ -269,15 +279,32 @@ void Child::run() {
free(xmlString);
}
+ if (gSessionData->kmod.isMaliCapture() && (gSessionData->mSampleRate == 0)) {
+ logg->logError(__FILE__, __LINE__, "Mali counters are not supported with Sample Rate: None.");
+ handleException();
+ }
+
// Must be after session XML is parsed
if (!primarySource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
+ if (gSessionData->perf.isSetup()) {
+ logg->logError(__FILE__, __LINE__, "Unable to prepare gator driver for capture");
+ } else {
+ logg->logError(__FILE__, __LINE__, "Unable to communicate with the perf API, please ensure that CONFIG_TRACING and CONFIG_CONTEXT_SWITCH_TRACER are enabled. Please refer to README_Streamline.txt for more information.");
+ }
handleException();
}
// Sender thread shall be halted until it is signaled for one shot mode
sem_init(&haltPipeline, 0, gSessionData->mOneShot ? 0 : 2);
+ // Must be initialized before senderThread is started as senderThread checks externalSource
+ externalSource = new ExternalSource(&senderSem);
+ if (!externalSource->prepare()) {
+ logg->logError(__FILE__, __LINE__, "Unable to prepare external source for capture");
+ handleException();
+ }
+ externalSource->start();
+
// Create the duration, stop, and sender threads
bool thread_creation_success = true;
if (gSessionData->mDuration > 0 && pthread_create(&durationThreadID, NULL, durationThread, NULL)) {
@@ -288,22 +315,37 @@ void Child::run() {
thread_creation_success = false;
}
- externalSource = new ExternalSource(&senderSem);
- if (!externalSource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
- handleException();
+ bool startUSSource = false;
+ for (int i = 0; i < ARRAY_LENGTH(gSessionData->usDrivers); ++i) {
+ if (gSessionData->usDrivers[i]->countersEnabled()) {
+ startUSSource = true;
+ }
}
- externalSource->start();
-
- if (gSessionData->hwmon.countersEnabled() || gSessionData->fsDriver.countersEnabled()) {
+ if (startUSSource) {
userSpaceSource = new UserSpaceSource(&senderSem);
if (!userSpaceSource->prepare()) {
- logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
+ logg->logError(__FILE__, __LINE__, "Unable to prepare userspace source for capture");
handleException();
}
userSpaceSource->start();
}
+ if (gSessionData->ftraceDriver.countersEnabled()) {
+ ftraceSource = new FtraceSource(&senderSem);
+ if (!ftraceSource->prepare()) {
+ logg->logError(__FILE__, __LINE__, "Unable to prepare userspace source for capture");
+ handleException();
+ }
+ ftraceSource->start();
+ }
+
+ if (gSessionData->mAllowCommands && (gSessionData->mCaptureCommand != NULL)) {
+ pthread_t thread;
+ if (pthread_create(&thread, NULL, commandThread, NULL)) {
+ thread_creation_success = false;
+ }
+ }
+
if (!thread_creation_success) {
logg->logError(__FILE__, __LINE__, "Failed to create gator threads");
handleException();
@@ -315,6 +357,9 @@ void Child::run() {
// Start profiling
primarySource->run();
+ if (ftraceSource != NULL) {
+ ftraceSource->join();
+ }
if (userSpaceSource != NULL) {
userSpaceSource->join();
}
@@ -338,6 +383,7 @@ void Child::run() {
logg->logMessage("Profiling ended.");
+ delete ftraceSource;
delete userSpaceSource;
delete externalSource;
delete primarySource;