Lower JIT thread priority

Modify the JIT thread to run at a lower priority in order to allow
UI-critical threads to get enough CPU time.

Bug: 27417985

(cherry picked from commit e701f088f8fe3a2c1f16e2895402f26283f4bcc7)

Change-Id: I5b962a7970ae81dac9e01a8011128c538cd78e40
diff --git a/runtime/jit/jit_instrumentation.cc b/runtime/jit/jit_instrumentation.cc
index a4e40ad..46c362a 100644
--- a/runtime/jit/jit_instrumentation.cc
+++ b/runtime/jit/jit_instrumentation.cc
@@ -25,6 +25,9 @@
 namespace art {
 namespace jit {
 
+// At what priority to schedule jit threads. 9 is the lowest foreground priority on device.
+static constexpr int kJitPoolThreadPthreadPriority = 9;
+
 class JitCompileTask FINAL : public Task {
  public:
   enum TaskKind {
@@ -92,6 +95,7 @@
   // There is a DCHECK in the 'AddSamples' method to ensure the tread pool
   // is not null when we instrument.
   thread_pool_.reset(new ThreadPool("Jit thread pool", 1));
+  thread_pool_->SetPthreadPriority(kJitPoolThreadPthreadPriority);
   thread_pool_->StartWorkers(Thread::Current());
   {
     // Add Jit interpreter instrumentation, tells the interpreter when
diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc
index 5a4dfb8..2fba805 100644
--- a/runtime/thread_pool.cc
+++ b/runtime/thread_pool.cc
@@ -16,6 +16,11 @@
 
 #include "thread_pool.h"
 
+#include <pthread.h>
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
 #include "base/bit_utils.h"
 #include "base/casts.h"
 #include "base/logging.h"
@@ -53,6 +58,19 @@
   CHECK_PTHREAD_CALL(pthread_join, (pthread_, nullptr), "thread pool worker shutdown");
 }
 
+void ThreadPoolWorker::SetPthreadPriority(int priority) {
+  CHECK_GE(priority, PRIO_MIN);
+  CHECK_LE(priority, PRIO_MAX);
+#if defined(__ANDROID__)
+  int result = setpriority(PRIO_PROCESS, pthread_gettid_np(pthread_), priority);
+  if (result != 0) {
+    PLOG(ERROR) << "Failed to setpriority to :" << priority;
+  }
+#else
+  UNUSED(priority);
+#endif
+}
+
 void ThreadPoolWorker::Run() {
   Thread* self = Thread::Current();
   Task* task = nullptr;
@@ -214,4 +232,10 @@
   return tasks_.size();
 }
 
+void ThreadPool::SetPthreadPriority(int priority) {
+  for (ThreadPoolWorker* worker : threads_) {
+    worker->SetPthreadPriority(priority);
+  }
+}
+
 }  // namespace art
diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h
index 6cd4ad3..b6c6f02 100644
--- a/runtime/thread_pool.h
+++ b/runtime/thread_pool.h
@@ -59,6 +59,9 @@
 
   virtual ~ThreadPoolWorker();
 
+  // Set the "nice" priorty for this worker.
+  void SetPthreadPriority(int priority);
+
  protected:
   ThreadPoolWorker(ThreadPool* thread_pool, const std::string& name, size_t stack_size);
   static void* Callback(void* arg) REQUIRES(!Locks::mutator_lock_);
@@ -111,6 +114,9 @@
   // thread count of the thread pool.
   void SetMaxActiveWorkers(size_t threads) REQUIRES(!task_queue_lock_);
 
+  // Set the "nice" priorty for threads in the pool.
+  void SetPthreadPriority(int priority);
+
  protected:
   // get a task to run, blocks if there are no tasks left
   virtual Task* GetTask(Thread* self) REQUIRES(!task_queue_lock_);