NBLog periodic merging thread
Bug: 35468674
Test: no change in functionality, everything works as before
Change-Id: Id2cea243bc15767ca6803c9505bf23a18411500e
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3d1f268..c0918d4 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -129,6 +129,7 @@
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
+ mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
mPrimaryHardwareDev(NULL),
mAudioHwDevs(NULL),
mHardwareStatus(AUDIO_HW_IDLE),
@@ -163,6 +164,8 @@
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
+ mMediaLogNotifier->run("MediaLogNotifier");
+
#ifdef TEE_SINK
char value[PROPERTY_VALUE_MAX];
(void) property_get("ro.debuggable", value, "0");
@@ -1528,6 +1531,41 @@
mAudioFlinger->removeNotificationClient(mPid);
}
+// ----------------------------------------------------------------------------
+AudioFlinger::MediaLogNotifier::MediaLogNotifier()
+ : mPendingRequests(false) {}
+
+
+void AudioFlinger::MediaLogNotifier::requestMerge() {
+ AutoMutex _l(mMutex);
+ mPendingRequests = true;
+ mCond.signal();
+}
+
+bool AudioFlinger::MediaLogNotifier::threadLoop() {
+ // Wait until there are pending requests
+ {
+ AutoMutex _l(mMutex);
+ mPendingRequests = false; // to ignore past requests
+ while (!mPendingRequests) {
+ mCond.wait(mMutex);
+ // TODO may also need an exitPending check
+ }
+ mPendingRequests = false;
+ }
+ // Execute the actual MediaLogService binder call and ignore extra requests for a while
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
+ if (binder != 0) {
+ sp<IMediaLogService> mediaLogService(interface_cast<IMediaLogService>(binder));
+ mediaLogService->requestMergeWakeup();
+ }
+ usleep(kPostTriggerSleepPeriod);
+ return true;
+}
+
+void AudioFlinger::requestLogMerge() {
+ mMediaLogNotifier->requestMerge();
+}
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 44fd512..f9c4ffd 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -472,6 +472,38 @@
const sp<IAudioFlingerClient> mAudioFlingerClient;
};
+ // --- MediaLogNotifier ---
+ // Thread in charge of notifying MediaLogService to start merging.
+ // Receives requests from AudioFlinger's binder activity. It is used to reduce the amount of
+ // binder calls to MediaLogService in case of bursts of AudioFlinger binder calls.
+ class MediaLogNotifier : public Thread {
+ public:
+ MediaLogNotifier();
+
+ // Requests a MediaLogService notification. It's ignored if there has recently been another
+ void requestMerge();
+ private:
+ // Every iteration blocks waiting for a request, then interacts with MediaLogService to
+ // start merging.
+ // As every MediaLogService binder call is expensive, once it gets a request it ignores the
+ // following ones for a period of time.
+ virtual bool threadLoop() override;
+
+ bool mPendingRequests;
+
+ // Mutex and condition variable around mPendingRequests' value
+ Mutex mMutex;
+ Condition mCond;
+
+ // Duration of the sleep period after a processed request
+ static const int kPostTriggerSleepPeriod = 1000000;
+ };
+
+ const sp<MediaLogNotifier> mMediaLogNotifier;
+
+ // This is a helper that is called during incoming binder calls.
+ void requestLogMerge();
+
class TrackHandle;
class RecordHandle;
class RecordThread;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b10e42c..b247b64 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2953,6 +2953,10 @@
#endif
while (!exitPending())
{
+ // Log merge requests are performed during AudioFlinger binder transactions, but
+ // that does not cover audio playback. It's requested here for that reason.
+ mAudioFlinger->requestLogMerge();
+
cpuStats.sample(myName);
Vector< sp<EffectChain> > effectChains;