// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/thread_pool.h"
#include "vm/lockers.h"
#include "vm/os.h"
#include "vm/unit_test.h"

namespace dart {

DECLARE_FLAG(int, worker_timeout_millis);

// Some of these tests change VM flags, so they should run without a full VM
// startup to prevent races on the flag changes. None of the tests require full
// VM startup, so we do this for all of them.
#define THREAD_POOL_UNIT_TEST_CASE(name)                                       \
  static void name##helper();                                                  \
  UNIT_TEST_CASE(name) {                                                       \
    OSThread::Init();                                                          \
    name##helper();                                                            \
    /* Delete the current thread's TLS and set it's TLS to null. */            \
    /* If it is the last thread then the destructor would call */              \
    /* OSThread::Cleanup. */                                                   \
    OSThread* os_thread = OSThread::Current();                                 \
    OSThread::SetCurrent(nullptr);                                             \
    delete os_thread;                                                          \
  }                                                                            \
  void name##helper()

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_Create) {
  ThreadPool thread_pool;
}

class TestTask : public ThreadPool::Task {
 public:
  TestTask(Monitor* sync, bool* done) : sync_(sync), done_(done) {}

  // Before running the task, *done_ should be true. This lets the caller
  // ASSERT things knowing that the thread is still around. To unblock the
  // thread, the caller should take the lock, set *done_ to false, and Notify()
  // the monitor.
  virtual void Run() {
    {
      MonitorLocker ml(sync_);
      while (*done_) {
        ml.Wait();
      }
    }
    MonitorLocker ml(sync_);
    *done_ = true;
    ml.Notify();
  }

 private:
  Monitor* sync_;
  bool* done_;
};

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_RunOne) {
  ThreadPool thread_pool;
  Monitor sync;
  bool done = true;
  thread_pool.Run<TestTask>(&sync, &done);
  {
    MonitorLocker ml(&sync);
    done = false;
    ml.Notify();
    while (!done) {
      ml.Wait();
    }
  }
  EXPECT(done);

  // Do a sanity test on the worker stats.
  EXPECT_EQ(1U, thread_pool.workers_started());
  EXPECT(!thread_pool.has_pending_dead_worker());
}

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_RunMany) {
  const int kTaskCount = 100;
  ThreadPool thread_pool;
  Monitor sync[kTaskCount];
  bool done[kTaskCount];

  for (int i = 0; i < kTaskCount; i++) {
    done[i] = true;
    thread_pool.Run<TestTask>(&sync[i], &done[i]);
  }
  for (int i = 0; i < kTaskCount; i++) {
    MonitorLocker ml(&sync[i]);
    done[i] = false;
    ml.Notify();
    while (!done[i]) {
      ml.Wait();
    }
    EXPECT(done[i]);
  }
}

class SleepTask : public ThreadPool::Task {
 public:
  SleepTask(Monitor* sync, int* started_count, int* slept_count, int millis)
      : sync_(sync),
        started_count_(started_count),
        slept_count_(slept_count),
        millis_(millis) {}

  virtual void Run() {
    {
      MonitorLocker ml(sync_);
      *started_count_ = *started_count_ + 1;
      ml.Notify();
    }
    // Sleep so we can be sure the ThreadPool destructor blocks until we're
    // done.
    OS::Sleep(millis_);
    {
      MonitorLocker ml(sync_);
      *slept_count_ = *slept_count_ + 1;
      // No notification here. The main thread is blocked in ThreadPool
      // shutdown waiting for this thread to finish.
    }
  }

 private:
  Monitor* sync_;
  int* started_count_;
  int* slept_count_;
  int millis_;
};

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_WorkerShutdown) {
  const int kTaskCount = 10;
  Monitor sync;
  int slept_count = 0;
  int started_count = 0;

  // Set up the ThreadPool so that workers notify before they exit.
  ThreadPool* thread_pool = new ThreadPool();

  // Run a single task.
  for (int i = 0; i < kTaskCount; i++) {
    thread_pool->Run<SleepTask>(&sync, &started_count, &slept_count, 2);
  }

  {
    // Wait for everybody to start.
    MonitorLocker ml(&sync);
    while (started_count < kTaskCount) {
      ml.Wait();
    }
  }

  // Kill the thread pool while the workers are sleeping.
  delete thread_pool;
  thread_pool = nullptr;

  int final_count = 0;
  {
    MonitorLocker ml(&sync);
    final_count = slept_count;
  }

  // We should have waited for all the workers to finish, so they all should
  // have had a chance to increment slept_count.
  EXPECT_EQ(kTaskCount, final_count);
}

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_WorkerTimeout) {
  // Adjust the worker timeout so that we timeout quickly.
  int saved_timeout = FLAG_worker_timeout_millis;
  FLAG_worker_timeout_millis = 1;

  {
    ThreadPool thread_pool;
    EXPECT_EQ(0U, thread_pool.workers_started());
    EXPECT(!thread_pool.has_pending_dead_worker());

    // Run a worker.
    Monitor sync;
    bool done = true;
    thread_pool.Run<TestTask>(&sync, &done);
    EXPECT_EQ(1U, thread_pool.workers_started());
    EXPECT(!thread_pool.has_pending_dead_worker());

    {
      MonitorLocker ml(&sync);
      done = false;
      ml.Notify();
      while (!done) {
        ml.Wait();
      }
    }
    EXPECT(done);

    // Wait up to 5 seconds to see if a worker times out.
    const int kMaxWait = 5000;
    int waited = 0;
    while (!thread_pool.has_pending_dead_worker() && waited < kMaxWait) {
      OS::Sleep(1);
      waited += 1;
    }
    EXPECT(thread_pool.has_pending_dead_worker());
  }

  FLAG_worker_timeout_millis = saved_timeout;
}

class SpawnTask : public ThreadPool::Task {
 public:
  SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done)
      : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) {}

  virtual void Run() {
    todo_--;  // Subtract one for current task.
    int child_todo = todo_ / 2;

    // Spawn 0-2 children.
    if (todo_ > 0) {
      pool_->Run<SpawnTask>(pool_, sync_, todo_ - child_todo, total_, done_);
    }
    if (todo_ > 1) {
      pool_->Run<SpawnTask>(pool_, sync_, child_todo, total_, done_);
    }

    {
      MonitorLocker ml(sync_);
      (*done_)++;
      if (*done_ >= total_) {
        ml.Notify();
      }
    }
  }

 private:
  ThreadPool* pool_;
  Monitor* sync_;
  int todo_;
  int total_;
  int* done_;
};

THREAD_POOL_UNIT_TEST_CASE(ThreadPool_RecursiveSpawn) {
  ThreadPool thread_pool;
  Monitor sync;
  const int kTotalTasks = 500;
  int done = 0;
  thread_pool.Run<SpawnTask>(&thread_pool, &sync, kTotalTasks, kTotalTasks,
                             &done);
  {
    MonitorLocker ml(&sync);
    while (done < kTotalTasks) {
      ml.Wait();
    }
  }
  EXPECT_EQ(kTotalTasks, done);
}

}  // namespace dart
