summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-07-23 14:54:04 -0700
committerJohn Reck <jreck@google.com>2014-07-23 22:28:44 +0000
commit73b7a4db4116774156fda3a510cc3afa14be9ffd (patch)
tree928ca1b91bd9e5e8d88ce58069a6d0027d37f965
parentdf8f55948a20a0f1673274ea904eeaf8031c7d57 (diff)
downloadframeworks_base-73b7a4db4116774156fda3a510cc3afa14be9ffd.zip
frameworks_base-73b7a4db4116774156fda3a510cc3afa14be9ffd.tar.gz
frameworks_base-73b7a4db4116774156fda3a510cc3afa14be9ffd.tar.bz2
Dump RenderThread stack on unresponsive
Bug: 16408405 Change-Id: I4ba4836fd1451fb8ba77c34cdb843d3cb4217bb8
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp3
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp3
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp17
-rw-r--r--libs/hwui/renderthread/RenderThread.h6
4 files changed, 25 insertions, 4 deletions
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index dd34e09..763e727 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -85,8 +85,7 @@ int DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos
void DrawFrameTask::postAndWait() {
AutoMutex _lock(mLock);
- mRenderThread->queue(this);
- mSignal.wait(mLock);
+ mRenderThread->queueAndWait(this, mSignal, mLock);
}
void DrawFrameTask::run() {
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 6cd3d0b..91f5801 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -405,8 +405,7 @@ void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
task->setReturnPtr(&retval);
SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
AutoMutex _lock(mSyncMutex);
- mRenderThread.queue(&syncTask);
- mSyncCondition.wait(mSyncMutex);
+ mRenderThread.queueAndWait(&syncTask, mSyncCondition, mSyncMutex);
return retval;
}
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 03e98d5..32dc46e 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -20,6 +20,7 @@
#include <gui/DisplayEventReceiver.h>
#include <utils/Log.h>
+#include <pthread.h>
#include "../RenderState.h"
#include "CanvasContext.h"
@@ -136,6 +137,7 @@ public:
};
RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>()
+ , mThreadId(0)
, mNextWakeup(LLONG_MAX)
, mDisplayEventReceiver(0)
, mVsyncRequested(false)
@@ -244,6 +246,7 @@ void RenderThread::requestVsync() {
}
bool RenderThread::threadLoop() {
+ mThreadId = pthread_self();
initThreadLocals();
int timeoutMillis = -1;
@@ -289,6 +292,16 @@ void RenderThread::queue(RenderTask* task) {
}
}
+void RenderThread::queueAndWait(RenderTask* task, Condition& signal, Mutex& lock) {
+ static nsecs_t sTimeout = milliseconds(500);
+ queue(task);
+ status_t err = signal.waitRelative(lock, sTimeout);
+ if (CC_UNLIKELY(err != NO_ERROR)) {
+ ALOGE("Timeout waiting for RenderTherad! err=%d", err);
+ nukeFromOrbit();
+ }
+}
+
void RenderThread::queueAtFront(RenderTask* task) {
AutoMutex _lock(mLock);
mQueue.queueAtFront(task);
@@ -341,6 +354,10 @@ RenderTask* RenderThread::nextTask(nsecs_t* nextWakeup) {
return next;
}
+void RenderThread::nukeFromOrbit() {
+ pthread_kill(mThreadId, SIGABRT);
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 0b91e9d..5984373 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -23,6 +23,7 @@
#include <set>
#include <cutils/compiler.h>
+#include <utils/Condition.h>
#include <utils/Looper.h>
#include <utils/Mutex.h>
#include <utils/Singleton.h>
@@ -73,6 +74,7 @@ public:
// RenderThread takes complete ownership of tasks that are queued
// and will delete them after they are run
ANDROID_API void queue(RenderTask* task);
+ void queueAndWait(RenderTask* task, Condition& signal, Mutex& lock);
ANDROID_API void queueAtFront(RenderTask* task);
void queueDelayed(RenderTask* task, int delayMs);
void remove(RenderTask* task);
@@ -106,11 +108,15 @@ private:
void dispatchFrameCallbacks();
void requestVsync();
+ // VERY DANGEROUS HANDLE WITH EXTREME CARE
+ void nukeFromOrbit();
+
// Returns the next task to be run. If this returns NULL nextWakeup is set
// to the time to requery for the nextTask to run. mNextWakeup is also
// set to this time
RenderTask* nextTask(nsecs_t* nextWakeup);
+ pthread_t mThreadId;
sp<Looper> mLooper;
Mutex mLock;