Jit: Fix for [Issue 2406862] Compiler thread preventing VM from shutting down

Replace placeholder sleep with timed condition wait that will start
the jit either when the framework signals that the first screen has been
drawn or a fixed time has elapsed.
diff --git a/vm/Sync.c b/vm/Sync.c
index acd916c..5340d86 100644
--- a/vm/Sync.c
+++ b/vm/Sync.c
@@ -504,7 +504,7 @@
 /*
  * Converts the given relative waiting time into an absolute time.
  */
-static void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
+void dvmAbsoluteTime(s8 msec, s4 nsec, struct timespec *ts)
 {
     s8 endSec;
 
@@ -589,7 +589,7 @@
     if (msec == 0 && nsec == 0) {
         timed = false;
     } else {
-        absoluteTime(msec, nsec, &ts);
+        dvmAbsoluteTime(msec, nsec, &ts);
         timed = true;
     }
 
@@ -1987,4 +1987,3 @@
 }
 
 #endif /*WITH_DEADLOCK_PREDICTION*/
-
diff --git a/vm/Sync.h b/vm/Sync.h
index 0ce3ebc..0832608 100644
--- a/vm/Sync.h
+++ b/vm/Sync.h
@@ -146,6 +146,11 @@
 bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
 
 /*
+ * Converts the given relative time into an absolute time
+ */
+void dvmAbsoluteTime(s8 msec, s4 nsec, struct timespec *ts);
+
+/*
  * Debug.
  */
 void dvmDumpMonitorInfo(const char* msg);
diff --git a/vm/compiler/Compiler.c b/vm/compiler/Compiler.c
index ceb1da1..39b42cd 100644
--- a/vm/compiler/Compiler.c
+++ b/vm/compiler/Compiler.c
@@ -295,20 +295,8 @@
         goto fail;
     }
 
-    dvmInitMutex(&gDvmJit.compilerLock);
-    pthread_cond_init(&gDvmJit.compilerQueueActivity, NULL);
-    pthread_cond_init(&gDvmJit.compilerQueueEmpty, NULL);
-
     dvmLockMutex(&gDvmJit.compilerLock);
 
-    gDvmJit.haltCompilerThread = false;
-
-    /* Reset the work queue */
-    memset(gDvmJit.compilerWorkQueue, 0,
-           sizeof(CompilerWorkOrder) * COMPILER_WORK_QUEUE_SIZE);
-    gDvmJit.compilerWorkEnqueueIndex = gDvmJit.compilerWorkDequeueIndex = 0;
-    gDvmJit.compilerQueueLength = 0;
-
     /* Track method-level compilation statistics */
     gDvmJit.methodStatsTable =  dvmHashTableCreate(32, NULL);
 
@@ -370,13 +358,39 @@
 
 static void *compilerThreadStart(void *arg)
 {
+    int ret;
+    struct timespec ts;
+
     dvmChangeStatus(NULL, THREAD_VMWAIT);
 
     /*
      * Wait a little before recieving translation requests on the assumption
      * that process start-up code isn't worth compiling.
      */
-    usleep(1 * 1000 * 1000);
+
+    dvmLockMutex(&gDvmJit.compilerLock);
+    /*
+     * TUNING: once framework is calling VMRuntime.startJitCompilation,
+     * experiment with the delay time (and perhaps have target-dependent
+     * values?
+     */
+    dvmAbsoluteTime(1000, 0, &ts);
+#if defined(HAVE_TIMEDWAIT_MONOTONIC)
+    ret = pthread_cond_timedwait_monotonic(&gDvmJit.compilerQueueActivity,
+                                           &gDvmJit.compilerLock, &ts);
+#else
+    ret = pthread_cond_timedwait(&gDvmJit.compilerQueueActivity,
+                                 &gDvmJit.compilerLock, &ts);
+#endif
+    assert(ret == 0 || ret == ETIMEDOUT);
+
+    if (gDvmJit.haltCompilerThread) {
+        dvmUnlockMutex(&gDvmJit.compilerLock);
+        return NULL;
+    }
+
+    dvmUnlockMutex(&gDvmJit.compilerLock);
+
     compilerThreadStartup();
 
     dvmLockMutex(&gDvmJit.compilerLock);
@@ -459,8 +473,19 @@
 
 bool dvmCompilerStartup(void)
 {
+
+    dvmInitMutex(&gDvmJit.compilerLock);
+    dvmLockMutex(&gDvmJit.compilerLock);
+    pthread_cond_init(&gDvmJit.compilerQueueActivity, NULL);
+    pthread_cond_init(&gDvmJit.compilerQueueEmpty, NULL);
+
+    /* Reset the work queue */
+    gDvmJit.compilerWorkEnqueueIndex = gDvmJit.compilerWorkDequeueIndex = 0;
+    gDvmJit.compilerQueueLength = 0;
+    dvmUnlockMutex(&gDvmJit.compilerLock);
+
     /*
-     * Defer initialization until we're sure JIT'ng makes sense.  Launch
+     * Defer rest of initialization until we're sure JIT'ng makes sense. Launch
      * the compiler thread, which will do the real initialization if and
      * when it is signalled to do so.
      */
diff --git a/vm/native/dalvik_system_VMRuntime.c b/vm/native/dalvik_system_VMRuntime.c
index 946a427..df0e73b 100644
--- a/vm/native/dalvik_system_VMRuntime.c
+++ b/vm/native/dalvik_system_VMRuntime.c
@@ -188,10 +188,15 @@
     JValue* pResult)
 {
 #if defined(WITH_JIT)
+#if 0
     /*
-     * TODO - experiment the timing and put code here to start JIT'ing
+     * TODO - experiment with the timing.
      * The tentative plan is onResume() will invoke the callback.
      */
+    dvmLockMutex(&gDvmJit.compilerLock);
+    pthread_cond_signal(&gDvmJit.compilerQueueActivity);
+    dvmUnlockMutex(&gDvmJit.compilerLock);
+#endif
 #endif
 
     RETURN_VOID();