If a finalizer wedges, raise prio and retry.

The VM uses a watchdog mechanism to detect stuck finalizers.  It appears
that, in some cases, the watchdog may be firing because the HeapWorker
thread in a background process doesn't get any CPU time after a
remotely-induced GC finishes.  With this change, if the HeapWorker is
running at a reduced priority, we raise the priority and allow it to
try some more.

No attempt is made to put the thread priority back.  (The HeapWorker
thread doesn't do anything in an idle process, and what it does do is
geared toward freeing one kind of resource or another.)

For bug 2492196.

Change-Id: Ic734c2e2819b9d60d20b2961f2a75085d5879495
diff --git a/vm/Thread.c b/vm/Thread.c
index b2d5776..9375921 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -30,8 +30,6 @@
 #include <errno.h>
 #include <fcntl.h>
 
-#include <cutils/sched_policy.h>
-
 #if defined(HAVE_PRCTL)
 #include <sys/prctl.h>
 #endif
@@ -2490,9 +2488,6 @@
     //abort();
 }
 
-/* "change flags" values for next two functions */
-enum { kChangedPriority = 0x01, kChangedPolicy = 0x02 };
-
 /*
  * If the thread is running at below-normal priority, temporarily elevate
  * it to "normal".
@@ -2501,7 +2496,7 @@
  * indicating what was changed, storing the previous values in the
  * provided locations.
  */
-static int raiseThreadPriorityIfNeeded(Thread* thread, int* pSavedThreadPrio,
+int dvmRaiseThreadPriorityIfNeeded(Thread* thread, int* pSavedThreadPrio,
     SchedPolicy* pSavedThreadPolicy)
 {
     errno = 0;
@@ -2554,7 +2549,7 @@
 /*
  * Reset the priority values for the thread in question.
  */
-static void resetThreadPriority(Thread* thread, int changeFlags,
+void dvmResetThreadPriority(Thread* thread, int changeFlags,
     int savedThreadPrio, SchedPolicy savedThreadPolicy)
 {
     if ((changeFlags & kChangedPolicy) != 0) {
@@ -2632,7 +2627,7 @@
              */
             if (retryCount == 2) {
                 assert(thread->systemTid != 0);
-                priChangeFlags = raiseThreadPriorityIfNeeded(thread,
+                priChangeFlags = dvmRaiseThreadPriorityIfNeeded(thread,
                     &savedThreadPrio, &savedThreadPolicy);
             }
         }
@@ -2687,7 +2682,7 @@
         //dvmDumpThread(thread, false);   /* suspended, so dump is safe */
     }
     if (priChangeFlags != 0) {
-        resetThreadPriority(thread, priChangeFlags, savedThreadPrio,
+        dvmResetThreadPriority(thread, priChangeFlags, savedThreadPrio,
             savedThreadPolicy);
     }
 }
@@ -3158,6 +3153,27 @@
     return (Thread*) vmData;
 }
 
+/*
+ * Given a pthread handle, return the associated Thread*.
+ * Caller must NOT hold the thread list lock.
+ *
+ * Returns NULL if the thread was not found.
+ */
+Thread* dvmGetThreadByHandle(pthread_t handle)
+{
+    dvmLockThreadList(NULL);
+    Thread* thread = gDvm.threadList;
+    while (thread != NULL) {
+        if (thread->handle == handle)
+            break;
+
+        thread = thread->next;
+    }
+    dvmUnlockThreadList();
+
+    return thread;
+}
+
 
 /*
  * Conversion map for "nice" values.