Merge "audioflinger: add watchdog on main mutex" into nyc-mr1-dev
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 8b831f0..05dacac 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -3,7 +3,8 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- ServiceUtilities.cpp
+ ServiceUtilities.cpp \
+ LockWatch.cpp
# FIXME Move this library to frameworks/native
LOCAL_MODULE := libserviceutility
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 79f4a66..c32eadd 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -246,7 +246,9 @@
}
mPatchPanel = new PatchPanel(this);
-
+ // FIXME: bug 30737845: trigger audioserver restart if main audioflinger lock
+ // is held continuously for more than 3 seconds
+ mLockWatch = new LockWatch(mLock, String8("AudioFlinger"));
mMode = AUDIO_MODE_NORMAL;
}
@@ -279,6 +281,7 @@
}
}
}
+ mLockWatch->requestExitAndWait();
}
static const char * const audio_interfaces[] = {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index c56dcc1..e334d80 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -58,6 +58,7 @@
#include "SpdifStreamOut.h"
#include "AudioHwDevice.h"
#include "LinearMap.h"
+#include "LockWatch.h"
#include <powermanager/IPowerManager.h>
@@ -630,6 +631,7 @@
};
mutable Mutex mLock;
+ sp<LockWatch> mLockWatch;
// protects mClients and mNotificationClients.
// must be locked after mLock and ThreadBase::mLock if both must be locked
// avoids acquiring AudioFlinger::mLock from inside thread loop.
diff --git a/services/audioflinger/LockWatch.cpp b/services/audioflinger/LockWatch.cpp
new file mode 100644
index 0000000..21eed6e
--- /dev/null
+++ b/services/audioflinger/LockWatch.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LockWatch"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include "LockWatch.h"
+
+namespace android {
+
+void LockWatch::onFirstRef()
+{
+ run("lock watch", ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+bool LockWatch::threadLoop()
+{
+ while (!exitPending()) {
+ // we neglect previous lock time effect on period
+ usleep(mPeriodMs * 1000);
+ if (mLock.timedLock(milliseconds(mTimeOutMs)) != NO_ERROR) {
+ LOG_ALWAYS_FATAL("LockWatch timeout for: %s", mTag.string());
+ }
+ mLock.unlock();
+ }
+ return false;
+}
+
+} // namespace android
+
diff --git a/services/audioflinger/LockWatch.h b/services/audioflinger/LockWatch.h
new file mode 100644
index 0000000..2d30217
--- /dev/null
+++ b/services/audioflinger/LockWatch.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef LOCK_WATCH_H
+#define LOCK_WATCH_H
+
+#include <utils/String8.h>
+#include <utils/Thread.h>
+
+namespace android {
+
+// periodically checks if a mutex can be acquired and kill process otherwise
+class LockWatch : public Thread {
+
+public:
+ static const uint32_t DEFAULT_PERIOD_MS = 10000; // 10 seconds default check period
+ static const uint32_t DEFAULT_TIMEOUT_MS = 3000; // 3 seconds default lock timeout
+
+ LockWatch(Mutex& lock, const String8& tag = String8(""),
+ uint32_t periodMs = DEFAULT_PERIOD_MS, uint32_t timeoutMs = DEFAULT_TIMEOUT_MS)
+ : Thread(false /*canCallJava*/),
+ mLock(lock), mTag(tag), mPeriodMs(periodMs), mTimeOutMs(timeoutMs) {}
+
+ virtual ~LockWatch() { }
+
+ // RefBase
+ virtual void onFirstRef();
+
+private:
+ // Thread
+ virtual bool threadLoop();
+
+ Mutex& mLock; // monitored mutex
+ String8 mTag; // tag
+ uint32_t mPeriodMs; // check period in milliseconds
+ uint32_t mTimeOutMs; // mutex lock timeout in milliseconds
+};
+
+} // namespace android
+
+#endif // LOCK_WATCH_H