Dump RenderThread stack on unresponsive

 Bug: 16408405

Change-Id: I4ba4836fd1451fb8ba77c34cdb843d3cb4217bb8
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 @@
 
 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 @@
     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 @@
 };
 
 RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>()
+        , mThreadId(0)
         , mNextWakeup(LLONG_MAX)
         , mDisplayEventReceiver(0)
         , mVsyncRequested(false)
@@ -244,6 +246,7 @@
 }
 
 bool RenderThread::threadLoop() {
+    mThreadId = pthread_self();
     initThreadLocals();
 
     int timeoutMillis = -1;
@@ -289,6 +292,16 @@
     }
 }
 
+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 @@
     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 @@
     // 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 @@
     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;