Separate analysis for each source file location

Use a map of maps of PerformanceAnalysis. The
first key is the thread, the second key the
source file location.

Test: dumpsys media.log
Change-Id: Ib60758e10ce1ddbf65337419db2ff3aa070763fb
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index 0adeb46..08f0944 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -49,20 +49,25 @@
 *
 * 2) reading the data from shared memory
 * Thread::threadloop()
-*     TODO: add description?
 * NBLog::MergeThread::threadLoop()
-*     calls NBLog::Merger::merge
+*     Waits on a mutex, called periodically
+*     Calls NBLog::Merger::merge and MergeReader.getAndProcessSnapshot.
 * NBLog::Merger::merge
 *     Merges snapshots sorted by timestamp
-*     for each reader in vector of class NamedReader,
-*     callsNamedReader::reader()->getSnapshot
-*     TODO: check whether the rest of this function is relevant
+*     Calls Reader::getSnapshot on each individual thread buffer to in shared
+*     memory and writes all their data to the single FIFO stored in mMerger.
 * NBLog::Reader::getSnapshot
 *     copies snapshot of reader's fifo buffer into its own buffer
 *     calls mFifoReader->obtain to find readable data
 *     sets snapshot.begin() and .end() iterators to boundaries of valid entries
 *     moves the fifo reader index to after the last entry read
 *     in this case, the buffer is in shared memory. in (4), the buffer is private
+* NBLog::MergeThread::getAndProcessSnapshot
+*     Iterates through the entries in the local FIFO. Processes the data in
+*     specific ways depending on the entry type. If the data is a histogram
+*     timestamp or an audio on/off signal, writes to a map of PerformanceAnalysis
+*     class instances, where the wakeup() intervals are stored as histograms
+*     and analyzed.
 *
 * 3) reading the data from private buffer
 * MediaLogService::dump
@@ -876,8 +881,7 @@
 void NBLog::MergeReader::getAndProcessSnapshot(NBLog::Reader::Snapshot &snapshot)
 {
     String8 timestamp, body;
-    // TODO: check: is the FIXME below still a problem?
-    // FIXME: this is not thread safe
+    // TODO: check: is this thread safe?
     // TODO: add lost data information and notification to ReportPerformance
     size_t lost = snapshot.lost() + (snapshot.begin() - EntryIterator(snapshot.data()));
     if (lost > 0) {
@@ -899,7 +903,7 @@
             memcpy(&hash, &(data->hash), sizeof(hash));
             int64_t ts;
             memcpy(&ts, &data->ts, sizeof(ts));
-            mThreadPerformanceAnalysis[data->author].logTsEntry(ts);
+            mThreadPerformanceAnalysis[data->author][hash].logTsEntry(ts);
             ++entry;
             break;
         }
@@ -907,12 +911,9 @@
             HistTsEntryWithAuthor *data = (HistTsEntryWithAuthor *) (entry->data);
             // TODO This memcpies are here to avoid unaligned memory access crash.
             // There's probably a more efficient way to do it
-            // TODO: incorporate hash information in mThreadPerformanceAnalysis
-            // log_hash_t hash;
-            // memcpy(&hash, &(data->hash), sizeof(hash));
-            // int64_t ts;
-            // memcpy(&ts, &data->ts, sizeof(ts));
-            mThreadPerformanceAnalysis[data->author].handleStateChange();
+            log_hash_t hash;
+            memcpy(&hash, &(data->hash), sizeof(hash));
+            mThreadPerformanceAnalysis[data->author][hash].handleStateChange();
             ++entry;
             break;
         }
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnbaio/PerformanceAnalysis.cpp
index 37d6d9f..698d592 100644
--- a/media/libnbaio/PerformanceAnalysis.cpp
+++ b/media/libnbaio/PerformanceAnalysis.cpp
@@ -348,11 +348,12 @@
 //------------------------------------------------------------------------------
 
 // writes summary of performance into specified file descriptor
-void dump(int fd, int indent, const std::map<int, PerformanceAnalysis>
-          &threadPerformanceAnalysis) {
+void dump(int fd, int indent, const PerformanceAnalysisMap &threadPerformanceAnalysis) {
     String8 body;
     for (auto & thread : threadPerformanceAnalysis) {
-        thread.second.reportPerformance(&body);
+        for (auto & hash: thread.second) {
+            hash.second.reportPerformance(&body);
+        }
     }
     if (!body.isEmpty()) {
         dumpLine(fd, indent, body);
diff --git a/media/libnbaio/include/media/nbaio/NBLog.h b/media/libnbaio/include/media/nbaio/NBLog.h
index b4af58b..bd17674 100644
--- a/media/libnbaio/include/media/nbaio/NBLog.h
+++ b/media/libnbaio/include/media/nbaio/NBLog.h
@@ -557,7 +557,9 @@
         const std::vector<NamedReader>& mNamedReaders;
 
         // analyzes, compresses and stores the merged data
-        std::map<int, ReportPerformance::PerformanceAnalysis> mThreadPerformanceAnalysis;
+        // contains a separate instance for every author (thread), and for every source file
+        // location within each author
+        ReportPerformance::PerformanceAnalysisMap mThreadPerformanceAnalysis;
 
         // handle author entry by looking up the author's name and appending it to the body
         // returns number of bytes read from fmtEntry
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
index 67bd3ac..dff307d 100644
--- a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
+++ b/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
@@ -134,8 +134,11 @@
 
 };
 
-void dump(int fd, int indent, const std::map<int, PerformanceAnalysis>
-          &threadPerformanceAnalysis);
+// 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 dumpLine(int fd, int indent, const String8 &body);