NBLog periodic merging thread
Bug: 35468674
Test: no change in functionality, everything works as before
Change-Id: Id2cea243bc15767ca6803c9505bf23a18411500e
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 255e350..4e2a0d5 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -935,7 +935,6 @@
}
return reply.readInt64();
}
-
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -945,6 +944,29 @@
status_t BnAudioFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
+ // Whitelist of relevant events to trigger log merging.
+ // Log merging should activate during audio activity of any kind. This are considered the
+ // most relevant events.
+ // TODO should select more wisely the items from the list
+ switch (code) {
+ case CREATE_TRACK:
+ case OPEN_RECORD:
+ case SET_MASTER_VOLUME:
+ case SET_MASTER_MUTE:
+ case SET_STREAM_VOLUME:
+ case SET_STREAM_MUTE:
+ case SET_MIC_MUTE:
+ case SET_PARAMETERS:
+ case OPEN_INPUT:
+ case SET_VOICE_VOLUME:
+ case CREATE_EFFECT:
+ case SYSTEM_READY: {
+ requestLogMerge();
+ break;
+ }
+ default:
+ break;
+ }
switch (code) {
case CREATE_TRACK: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index f480c16..b65ac99 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "NBLog"
//#define LOG_NDEBUG 0
+#include <climits>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -958,4 +959,42 @@
return NBLog::Entry::kOverhead + sizeof(author);
}
+NBLog::MergeThread::MergeThread(NBLog::Merger &merger)
+ : mMerger(merger),
+ mTimeoutUs(0) {}
+
+NBLog::MergeThread::~MergeThread() {
+ // set exit flag, set timeout to 0 to force threadLoop to exit and wait for the thread to join
+ requestExit();
+ setTimeoutUs(0);
+ join();
+}
+
+bool NBLog::MergeThread::threadLoop() {
+ bool doMerge;
+ {
+ AutoMutex _l(mMutex);
+ // If mTimeoutUs is negative, wait on the condition variable until it's positive.
+ // If it's positive, wait kThreadSleepPeriodUs and then merge
+ nsecs_t waitTime = mTimeoutUs > 0 ? kThreadSleepPeriodUs * 1000 : LLONG_MAX;
+ mCond.waitRelative(mMutex, waitTime);
+ doMerge = mTimeoutUs > 0;
+ mTimeoutUs -= kThreadSleepPeriodUs;
+ }
+ if (doMerge) {
+ mMerger.merge();
+ }
+ return true;
+}
+
+void NBLog::MergeThread::wakeup() {
+ setTimeoutUs(kThreadWakeupPeriodUs);
+}
+
+void NBLog::MergeThread::setTimeoutUs(int time) {
+ AutoMutex _l(mMutex);
+ mTimeoutUs = time;
+ mCond.signal();
+}
+
} // namespace android
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/NBLog.h
index 043f15e..369c22a 100644
--- a/media/libnbaio/include/NBLog.h
+++ b/media/libnbaio/include/NBLog.h
@@ -20,8 +20,9 @@
#define ANDROID_MEDIA_NBLOG_H
#include <binder/IMemory.h>
-#include <utils/Mutex.h>
#include <audio_utils/fifo.h>
+#include <utils/Mutex.h>
+#include <utils/threads.h>
#include <vector>
@@ -41,6 +42,7 @@
enum Event {
EVENT_RESERVED,
EVENT_STRING, // ASCII string, not NUL-terminated
+ // TODO: make timestamp optional
EVENT_TIMESTAMP, // clock_gettime(CLOCK_MONOTONIC)
EVENT_INTEGER, // integer value entry
EVENT_FLOAT, // floating point value entry
@@ -106,7 +108,7 @@
template<typename T>
inline const T& payload() {
- return *reinterpret_cast<const T *>(ptr + 2);
+ return *reinterpret_cast<const T *>(ptr + offsetof(entry, data));
}
private:
@@ -425,6 +427,43 @@
size_t handleAuthor(const FormatEntry &fmtEntry, String8 *body);
};
+// MergeThread is a thread that contains a Merger. It works as a retriggerable one-shot:
+// when triggered, it awakes for a lapse of time, during which it periodically merges; if
+// retriggered, the timeout is reset.
+// The thread is triggered on AudioFlinger binder activity.
+class MergeThread : public Thread {
+public:
+ MergeThread(Merger &merger);
+ virtual ~MergeThread() override;
+
+ // Reset timeout and activate thread to merge periodically if it's idle
+ void wakeup();
+
+ // Set timeout period until the merging thread goes idle again
+ void setTimeoutUs(int time);
+
+private:
+ virtual bool threadLoop() override;
+
+ // the merger who actually does the work of merging the logs
+ Merger& mMerger;
+
+ // mutex for the condition variable
+ Mutex mMutex;
+
+ // condition variable to activate merging on timeout >= 0
+ Condition mCond;
+
+ // time left until the thread blocks again (in microseconds)
+ int mTimeoutUs;
+
+ // merging period when the thread is awake
+ static const int kThreadSleepPeriodUs = 1000000 /*1s*/;
+
+ // initial timeout value when triggered
+ static const int kThreadWakeupPeriodUs = 3000000 /*3s*/;
+};
+
}; // class NBLog
} // namespace android