From 73b7a4db4116774156fda3a510cc3afa14be9ffd Mon Sep 17 00:00:00 2001 From: John Reck Date: Wed, 23 Jul 2014 14:54:04 -0700 Subject: [PATCH] Dump RenderThread stack on unresponsive Bug: 16408405 Change-Id: I4ba4836fd1451fb8ba77c34cdb843d3cb4217bb8 --- libs/hwui/renderthread/DrawFrameTask.cpp | 3 +-- libs/hwui/renderthread/RenderProxy.cpp | 3 +-- libs/hwui/renderthread/RenderThread.cpp | 17 +++++++++++++++++ libs/hwui/renderthread/RenderThread.h | 6 ++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index dd34e095738d..763e72747e83 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 6cd3d0bdb96b..91f5801d8b60 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 03e98d5b2f03..32dc46ee57eb 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "../RenderState.h" #include "CanvasContext.h" @@ -136,6 +137,7 @@ public: }; RenderThread::RenderThread() : Thread(true), Singleton() + , 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 0b91e9dd97aa..59843736f048 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -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 mLooper; Mutex mLock; -- 2.11.0