
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "thread_pool.h"

#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/time.h>

#include <pthread.h>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>

#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/stl_util.h"
#include "base/time_utils.h"
#include "base/utils.h"
#include "runtime.h"
#include "thread-current-inl.h"

namespace art HIDDEN {

using android::base::StringPrintf;

static constexpr bool kMeasureWaitTime = false;

#if defined(__BIONIC__)
static constexpr bool kUseCustomThreadPoolStack = false;
#else
static constexpr bool kUseCustomThreadPoolStack = true;
#endif

ThreadPoolWorker::ThreadPoolWorker(AbstractThreadPool* thread_pool,
                                   const std::string& name,
                                   size_t stack_size)
    : thread_pool_(thread_pool),
      name_(name) {
  std::string error_msg;
  // On Bionic, we know pthreads will give us a big-enough stack with
  // a guard page, so don't do anything special on Bionic libc.
  if (kUseCustomThreadPoolStack) {
    // Add an inaccessible page to catch stack overflow.
    stack_size += gPageSize;
    stack_ = MemMap::MapAnonymous(name.c_str(),
                                  stack_size,
                                  PROT_READ | PROT_WRITE,
                                  /*low_4gb=*/ false,
                                  &error_msg);
    CHECK(stack_.IsValid()) << error_msg;
    CHECK_ALIGNED_PARAM(stack_.Begin(), gPageSize);
    CheckedCall(mprotect,
                "mprotect bottom page of thread pool worker stack",
                stack_.Begin(),
                gPageSize,
                PROT_NONE);
  }
  const char* reason = "new thread pool worker thread";
  pthread_attr_t attr;
  CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason);
  if (kUseCustomThreadPoolStack) {
    CHECK_PTHREAD_CALL(pthread_attr_setstack, (&attr, stack_.Begin(), stack_.Size()), reason);
  } else {
    CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), reason);
  }
  CHECK_PTHREAD_CALL(pthread_create, (&pthread_, &attr, &Callback, this), reason);
  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason);
}

ThreadPoolWorker::~ThreadPoolWorker() {
  CHECK_PTHREAD_CALL(pthread_join, (pthread_, nullptr), "thread pool worker shutdown");
}

// Set the "nice" priority for tid (0 means self).
static void SetPriorityForTid(pid_t tid, int priority) {
  CHECK_GE(priority, PRIO_MIN);
  CHECK_LE(priority, PRIO_MAX);
  int result = setpriority(PRIO_PROCESS, tid, priority);
  if (result != 0) {
#if defined(ART_TARGET_ANDROID)
    PLOG(WARNING) << "Failed to setpriority to :" << priority;
#endif
    // Setpriority may fail on host due to ulimit issues.
  }
}

void ThreadPoolWorker::SetPthreadPriority(int priority) {
#if defined(ART_TARGET_ANDROID)
  SetPriorityForTid(pthread_gettid_np(pthread_), priority);
#else
  UNUSED(priority);
#endif
}

int ThreadPoolWorker::GetPthreadPriority() {
#if defined(ART_TARGET_ANDROID)
  return getpriority(PRIO_PROCESS, pthread_gettid_np(pthread_));
#else
  return 0;
#endif
}

void ThreadPoolWorker::Run() {
  Thread* self = Thread::Current();
  Task* task = nullptr;
  thread_pool_->creation_barier_.Pass(self);
  while ((task = thread_pool_->GetTask(self)) != nullptr) {
    task->Run(self);
    task->Finalize();
  }
}

void* ThreadPoolWorker::Callback(void* arg) {
  ThreadPoolWorker* worker = reinterpret_cast<ThreadPoolWorker*>(arg);
  Runtime* runtime = Runtime::Current();
  // Don't run callbacks for ThreadPoolWorkers. These are created for JITThreadPool and
  // HeapThreadPool and are purely internal threads of the runtime and we don't need to run
  // callbacks for the thread attach / detach listeners.
  // (b/251163712) Calling callbacks for heap thread pool workers causes deadlocks in some libjdwp
  // tests. Deadlocks happen when a GC thread is attached while libjdwp holds the event handler
  // lock for an event that triggers an entrypoint update from deopt manager.
  CHECK(runtime->AttachCurrentThread(
      worker->name_.c_str(),
      true,
      // Thread-groups are only tracked by the peer j.l.Thread objects. If we aren't creating peers
      // we don't need to specify the thread group. We want to place these threads in the System
      // thread group because that thread group is where important threads that debuggers and
      // similar tools should not mess with are placed. As this is an internal-thread-pool we might
      // rely on being able to (for example) wait for all threads to finish some task. If debuggers
      // are suspending these threads that might not be possible.
      worker->thread_pool_->create_peers_ ? runtime->GetSystemThreadGroup() : nullptr,
      worker->thread_pool_->create_peers_,
      /* should_run_callbacks= */ false));
  worker->thread_ = Thread::Current();
  // Mark thread pool workers as runtime-threads.
  worker->thread_->SetIsRuntimeThread(true);
  // Do work until its time to shut down.
  worker->Run();
  runtime->DetachCurrentThread(/* should_run_callbacks= */ false);
  // On zygote fork, we wait for this thread to exit completely. Set to highest Java priority
  // to speed that up.
  constexpr int kJavaMaxPrioNiceness = -8;
  SetPriorityForTid(0 /* this thread */, kJavaMaxPrioNiceness);
  return nullptr;
}

void ThreadPool::AddTask(Thread* self, Task* task) {
  MutexLock mu(self, task_queue_lock_);
  tasks_.push_back(task);
  // If we have any waiters, signal one.
  if (started_ && waiting_count_ != 0) {
    task_queue_condition_.Signal(self);
  }
}

void ThreadPool::RemoveAllTasks(Thread* self) {
  // The ThreadPool is responsible for calling Finalize (which usually delete
  // the task memory) on all the tasks.
  Task* task = nullptr;
  do {
    {
      MutexLock mu(self, task_queue_lock_);
      if (tasks_.empty()) {
        return;
      }
      task = tasks_.front();
      tasks_.pop_front();
    }
    task->Finalize();
  } while (true);
}

ThreadPool::~ThreadPool() {
  DeleteThreads();
  RemoveAllTasks(Thread::Current());
}

AbstractThreadPool::AbstractThreadPool(const char* name,
                                       size_t num_threads,
                                       bool create_peers,
                                       size_t worker_stack_size)
  : name_(name),
    task_queue_lock_("task queue lock", kGenericBottomLock),
    task_queue_condition_("task queue condition", task_queue_lock_),
    completion_condition_("task completion condition", task_queue_lock_),
    started_(false),
    shutting_down_(false),
    waiting_count_(0),
    start_time_(0),
    total_wait_time_(0),
    creation_barier_(0),
    max_active_workers_(num_threads),
    create_peers_(create_peers),
    worker_stack_size_(worker_stack_size) {}

void AbstractThreadPool::CreateThreads() {
  CHECK(threads_.empty());
  Thread* self = Thread::Current();
  {
    MutexLock mu(self, task_queue_lock_);
    shutting_down_ = false;
    // Add one since the caller of constructor waits on the barrier too.
    creation_barier_.Init(self, max_active_workers_);
    while (GetThreadCount() < max_active_workers_) {
      const std::string worker_name = StringPrintf("%s worker thread %zu", name_.c_str(),
                                                   GetThreadCount());
      threads_.push_back(
          new ThreadPoolWorker(this, worker_name, worker_stack_size_));
    }
  }
}

void AbstractThreadPool::WaitForWorkersToBeCreated() {
  creation_barier_.Increment(Thread::Current(), 0);
}

const std::vector<ThreadPoolWorker*>& AbstractThreadPool::GetWorkers() {
  // Wait for all the workers to be created before returning them.
  WaitForWorkersToBeCreated();
  return threads_;
}

void AbstractThreadPool::DeleteThreads() {
  {
    Thread* self = Thread::Current();
    MutexLock mu(self, task_queue_lock_);
    // Tell any remaining workers to shut down.
    shutting_down_ = true;
    // Broadcast to everyone waiting.
    task_queue_condition_.Broadcast(self);
    completion_condition_.Broadcast(self);
  }
  // Wait for the threads to finish. We expect the user of the pool
  // not to run multi-threaded calls to `CreateThreads` and `DeleteThreads`,
  // so we don't guard the field here.
  STLDeleteElements(&threads_);
}

void AbstractThreadPool::SetMaxActiveWorkers(size_t max_workers) {
  MutexLock mu(Thread::Current(), task_queue_lock_);
  CHECK_LE(max_workers, GetThreadCount());
  max_active_workers_ = max_workers;
}

void AbstractThreadPool::StartWorkers(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  started_ = true;
  task_queue_condition_.Broadcast(self);
  start_time_ = NanoTime();
  total_wait_time_ = 0;
}

void AbstractThreadPool::StopWorkers(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  started_ = false;
}

bool AbstractThreadPool::HasStarted(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  return started_;
}

Task* AbstractThreadPool::GetTask(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  while (!IsShuttingDown()) {
    const size_t thread_count = GetThreadCount();
    // Ensure that we don't use more threads than the maximum active workers.
    const size_t active_threads = thread_count - waiting_count_;
    // <= since self is considered an active worker.
    if (active_threads <= max_active_workers_) {
      Task* task = TryGetTaskLocked();
      if (task != nullptr) {
        return task;
      }
    }

    ++waiting_count_;
    if (waiting_count_ == GetThreadCount() && !HasOutstandingTasks()) {
      // We may be done, lets broadcast to the completion condition.
      completion_condition_.Broadcast(self);
    }
    const uint64_t wait_start = kMeasureWaitTime ? NanoTime() : 0;
    task_queue_condition_.Wait(self);
    if (kMeasureWaitTime) {
      const uint64_t wait_end = NanoTime();
      total_wait_time_ += wait_end - std::max(wait_start, start_time_);
    }
    --waiting_count_;
  }

  // We are shutting down, return null to tell the worker thread to stop looping.
  return nullptr;
}

Task* AbstractThreadPool::TryGetTask(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  return TryGetTaskLocked();
}

Task* ThreadPool::TryGetTaskLocked() {
  if (HasOutstandingTasks()) {
    Task* task = tasks_.front();
    tasks_.pop_front();
    return task;
  }
  return nullptr;
}

void AbstractThreadPool::Wait(Thread* self, bool do_work, bool may_hold_locks) {
  if (do_work) {
    CHECK(!create_peers_);
    Task* task = nullptr;
    while ((task = TryGetTask(self)) != nullptr) {
      task->Run(self);
      task->Finalize();
    }
  }
  // Wait until each thread is waiting and the task list is empty.
  MutexLock mu(self, task_queue_lock_);
  while (!shutting_down_ && (waiting_count_ != GetThreadCount() || HasOutstandingTasks())) {
    if (!may_hold_locks) {
      completion_condition_.Wait(self);
    } else {
      completion_condition_.WaitHoldingLocks(self);
    }
  }
}

size_t ThreadPool::GetTaskCount(Thread* self) {
  MutexLock mu(self, task_queue_lock_);
  return tasks_.size();
}

void AbstractThreadPool::SetPthreadPriority(int priority) {
  for (ThreadPoolWorker* worker : threads_) {
    worker->SetPthreadPriority(priority);
  }
}

void AbstractThreadPool::CheckPthreadPriority(int priority) {
#if defined(ART_TARGET_ANDROID)
  for (ThreadPoolWorker* worker : threads_) {
    CHECK_EQ(worker->GetPthreadPriority(), priority);
  }
#else
  UNUSED(priority);
#endif
}

}  // namespace art
