Write thread and data to separate files
Each file name starts with either "histogram" or
"outlier" and contains thread and hash (source
file location) information.
Test: dumpsys media.log
Change-Id: I4bbea8b5265ac539e6fb2ce16207e4f5c89d21d4
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnbaio/PerformanceAnalysis.cpp
index 698d592..d1dff47 100644
--- a/media/libnbaio/PerformanceAnalysis.cpp
+++ b/media/libnbaio/PerformanceAnalysis.cpp
@@ -73,7 +73,7 @@
return;
}
- // mHists is empty if program just started
+ // mHists is empty if thread/hash pair is sending data for the first time
if (mHists.empty()) {
mHists.emplace_front(static_cast<uint64_t>(mTimeStampSeries[0]),
std::map<int, int>());
@@ -130,10 +130,6 @@
}
}
-// TODO: move this someplace
-// static const char* const kName = (const char *) "/data/misc/audioserver/sample_results.txt";
-// writeToFile(mOutlierData, mLongTermHists, kName, false);
-
// Given a series of outlier intervals (mOutlier data),
// looks for changes in distribution (peaks), which can be either positive or negative.
// The function sets the mean to the starting value and sigma to 0, and updates
@@ -223,7 +219,6 @@
}
}
-
// FIXME: delete this temporary test code, recycled for various new functions
void PerformanceAnalysis::testFunction() {
// produces values (4: 5000000), (13: 18000000)
@@ -241,7 +236,10 @@
// TODO Make it return a std::string instead of modifying body --> is this still relevant?
// TODO consider changing all ints to uint32_t or uint64_t
// TODO: move this to ReportPerformance, probably make it a friend function of PerformanceAnalysis
-void PerformanceAnalysis::reportPerformance(String8 *body, int maxHeight) const {
+void PerformanceAnalysis::reportPerformance(String8 *body, int maxHeight) {
+ // Add any new data
+ processAndFlushTimeStampSeries();
+
if (mHists.empty()) {
ALOGD("reportPerformance: mHists is empty");
return;
@@ -348,11 +346,18 @@
//------------------------------------------------------------------------------
// writes summary of performance into specified file descriptor
-void dump(int fd, int indent, const PerformanceAnalysisMap &threadPerformanceAnalysis) {
+void dump(int fd, int indent, PerformanceAnalysisMap &threadPerformanceAnalysis) {
String8 body;
+ const char* const kName = "/data/misc/audioserver/";
for (auto & thread : threadPerformanceAnalysis) {
for (auto & hash: thread.second) {
- hash.second.reportPerformance(&body);
+ PerformanceAnalysis& curr = hash.second;
+ curr.processAndFlushTimeStampSeries();
+ // write performance data to console
+ curr.reportPerformance(&body);
+ // write to file
+ writeToFile(curr.mOutlierData, curr.mHists, kName, false,
+ thread.first, hash.first);
}
}
if (!body.isEmpty()) {
diff --git a/media/libnbaio/ReportPerformance.cpp b/media/libnbaio/ReportPerformance.cpp
index 7d3869c..87c223b 100644
--- a/media/libnbaio/ReportPerformance.cpp
+++ b/media/libnbaio/ReportPerformance.cpp
@@ -23,12 +23,12 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
+#include <sstream>
#include <sys/prctl.h>
#include <utility>
#include <media/nbaio/NBLog.h>
#include <media/nbaio/PerformanceAnalysis.h>
#include <media/nbaio/ReportPerformance.h>
-// #include <utils/CallStack.h> // used to print callstack
#include <utils/Log.h>
#include <utils/String8.h>
@@ -40,34 +40,48 @@
// TODO: format the data efficiently and write different types of data to different files
void writeToFile(const std::deque<std::pair<outlierInterval, timestamp>> &outlierData,
const std::deque<std::pair<timestamp, Histogram>> &hists,
- const char * kName,
- bool append) {
- ALOGD("writing performance data to file");
+ const char * kDirectory,
+ bool append, int author, log_hash_t hash) {
if (outlierData.empty() || hists.empty()) {
+ ALOGW("No data, returning.");
return;
}
+ std::stringstream outlierName;
+ std::stringstream histogramName;
+
+ outlierName << kDirectory << "outliers_" << author << "_" << hash;
+ histogramName << kDirectory << "histograms_" << author << "_" << hash;
+
std::ofstream ofs;
- ofs.open(kName, append ? std::ios::app : std::ios::trunc);
+ ofs.open(outlierName.str().c_str(), append ? std::ios::app : std::ios::trunc);
if (!ofs.is_open()) {
- ALOGW("couldn't open file %s", kName);
+ ALOGW("couldn't open file %s", outlierName.str().c_str());
return;
}
ofs << "Outlier data: interval and timestamp\n";
for (const auto &outlier : outlierData) {
ofs << outlier.first << ": " << outlier.second << "\n";
}
- ofs << "Histogram data\n";
- for (const auto &hist : hists) {
- ofs << "\ttimestamp\n";
- ofs << hist.first << "\n";
- ofs << "\tbuckets and counts\n";
- for (const auto &bucket : hist.second) {
- ofs << bucket.first << ": " << bucket.second << "\n";
- }
- ofs << "\n"; // separate histograms with a newline
- }
ofs.close();
+
+ std::ofstream hfs;
+ hfs.open(histogramName.str().c_str(), append ? std::ios::app : std::ios::trunc);
+ if (!hfs.is_open()) {
+ ALOGW("couldn't open file %s", histogramName.str().c_str());
+ return;
+ }
+ hfs << "Histogram data\n";
+ for (const auto &hist : hists) {
+ hfs << "\ttimestamp\n";
+ hfs << hist.first << "\n";
+ hfs << "\tbuckets and counts\n";
+ for (const auto &bucket : hist.second) {
+ hfs << bucket.first << ": " << bucket.second << "\n";
+ }
+ hfs << "\n"; // separate histograms with a newline
+ }
+ hfs.close();
}
} // namespace ReportPerformance
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
index dff307d..da68821 100644
--- a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
+++ b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
@@ -29,6 +29,12 @@
namespace ReportPerformance {
+class PerformanceAnalysis;
+
+// a map of PerformanceAnalysis instances
+// The outer key is for the thread, the inner key for the source file location.
+using PerformanceAnalysisMap = std::map<int, std::map<log_hash_t, PerformanceAnalysis>>;
+
class PerformanceAnalysis {
// This class stores and analyzes audio processing wakeup timestamps from NBLog
// FIXME: currently, all performance data is stored in deques. Need to add a mutex.
@@ -38,15 +44,13 @@
PerformanceAnalysis();
- // Given a series of audio processing wakeup timestamps,
- // compresses and and analyzes the data, and flushes
- // the timestamp series from memory.
- void processAndFlushTimeStampSeries();
+ friend void dump(int fd, int indent,
+ PerformanceAnalysisMap &threadPerformanceAnalysis);
// Given a series of audio processing wakeup timestamps,
// compresses and and analyzes the data, and flushes
// the timestamp series from memory.
- void processAndFlushTimeStampSeriesOld();
+ void processAndFlushTimeStampSeries();
// Called when an audio on/off event is read from the buffer,
// e.g. EVENT_AUDIO_STATE.
@@ -73,7 +77,7 @@
// input: series of short histograms. Generates a string of analysis of the buffer periods
// TODO: WIP write more detailed analysis
// FIXME: move this data visualization to a separate class. Model/view/controller
- void reportPerformance(String8 *body, int maxHeight = 10) const;
+ void reportPerformance(String8 *body, int maxHeight = 10);
// TODO: delete this. temp for testing
void testFunction();
@@ -134,12 +138,7 @@
};
-// a map of PerformanceAnalysis instances
-// The outer key is for the thread, the inner key for the source file location.
-using PerformanceAnalysisMap = std::map<int, std::map<log_hash_t, PerformanceAnalysis>>;
-
-void dump(int fd, int indent, const PerformanceAnalysisMap &threadPerformanceAnalysis);
-
+void dump(int fd, int indent, PerformanceAnalysisMap &threadPerformanceAnalysis);
void dumpLine(int fd, int indent, const String8 &body);
} // namespace ReportPerformance
diff --git a/media/libnbaio/include/media/nbaio/ReportPerformance.h b/media/libnbaio/include/media/nbaio/ReportPerformance.h
index e5b9840..afbbb75 100644
--- a/media/libnbaio/include/media/nbaio/ReportPerformance.h
+++ b/media/libnbaio/include/media/nbaio/ReportPerformance.h
@@ -58,8 +58,7 @@
// intervals to a file.
void writeToFile(const std::deque<std::pair<outlierInterval, timestamp>> &outlierData,
const std::deque<std::pair<timestamp, Histogram>> &hists,
- const char * kName,
- bool append);
+ const char * kName, bool append, int author, log_hash_t hash);
} // namespace ReportPerformance