// 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 "platform/assert.h"
#include "vm/heap/safepoint.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/profiler.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"
#include "vm/thread_pool.h"
#include "vm/unit_test.h"

namespace dart {

VM_UNIT_TEST_CASE(Mutex) {
  // This unit test case needs a running isolate.
  TestCase::CreateTestIsolate();
  Mutex* mutex = new Mutex();
  mutex->Lock();
  EXPECT_EQ(false, mutex->TryLock());
  mutex->Unlock();
  EXPECT_EQ(true, mutex->TryLock());
  mutex->Unlock();
  {
    MutexLocker ml(mutex);
    EXPECT_EQ(false, mutex->TryLock());
  }
  // The isolate shutdown and the destruction of the mutex are out-of-order on
  // purpose.
  Dart_ShutdownIsolate();
  delete mutex;
}

VM_UNIT_TEST_CASE(Monitor) {
  // This unit test case needs a running isolate.
  TestCase::CreateTestIsolate();
  OSThread* thread = OSThread::Current();
  // Thread interrupter interferes with this test, disable interrupts.
  thread->DisableThreadInterrupts();
  Monitor* monitor = new Monitor();
  monitor->Enter();
  monitor->Exit();
  EXPECT_EQ(true, monitor->TryEnter());
  monitor->Exit();

  const int kNumAttempts = 5;
  int attempts = 0;
  while (attempts < kNumAttempts) {
    MonitorLocker ml(monitor);
    int64_t start = OS::GetCurrentMonotonicMicros();
    int64_t wait_time = 2017;
    Monitor::WaitResult wait_result = ml.Wait(wait_time);
    int64_t stop = OS::GetCurrentMonotonicMicros();

    // We expect to be timing out here.
    EXPECT_EQ(Monitor::kTimedOut, wait_result);

    // Check whether this attempt falls within the expected time limits.
    int64_t wakeup_time = (stop - start) / kMicrosecondsPerMillisecond;
    OS::PrintErr("wakeup_time: %" Pd64 "\n", wakeup_time);
    const int kAcceptableTimeJitter = 20;    // Measured in milliseconds.
    const int kAcceptableWakeupDelay = 150;  // Measured in milliseconds.
    if (((wait_time - kAcceptableTimeJitter) <= wakeup_time) &&
        (wakeup_time <= (wait_time + kAcceptableWakeupDelay))) {
      break;
    }

    // Record the attempt.
    attempts++;
  }
  EXPECT_LT(attempts, kNumAttempts);

  // The isolate shutdown and the destruction of the mutex are out-of-order on
  // purpose.
  Dart_ShutdownIsolate();
  delete monitor;
}

class ObjectCounter : public ObjectPointerVisitor {
 public:
  explicit ObjectCounter(IsolateGroup* isolate_group, const Object* obj)
      : ObjectPointerVisitor(isolate_group), obj_(obj), count_(0) {}

  virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
    for (ObjectPtr* current = first; current <= last; ++current) {
      if (*current == obj_->ptr()) {
        ++count_;
      }
    }
  }

  intptr_t count() const { return count_; }

 private:
  const Object* obj_;
  intptr_t count_;
};

class TaskWithZoneAllocation : public ThreadPool::Task {
 public:
  TaskWithZoneAllocation(Isolate* isolate,
                         Monitor* monitor,
                         bool* done,
                         intptr_t id)
      : isolate_(isolate), monitor_(monitor), done_(done), id_(id) {}
  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
    {
      Thread* thread = Thread::Current();
      // Create a zone (which is also a stack resource) and exercise it a bit.
      StackZone stack_zone(thread);
      HANDLESCOPE(thread);
      Zone* zone = thread->zone();
      EXPECT_EQ(zone, stack_zone.GetZone());
      ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1);
      GrowableArray<bool> a1(zone, 1);
      for (intptr_t i = 0; i < 100000; ++i) {
        a0->Add(true);
        a1.Add(true);
      }
      // Check that we can create handles and allocate in old space.
      String& str = String::Handle(zone, String::New("old", Heap::kOld));
      EXPECT(str.Equals("old"));

      const intptr_t unique_smi = id_ + 928327281;
      Smi& smi = Smi::Handle(zone, Smi::New(unique_smi));
      EXPECT(smi.Value() == unique_smi);
      {
        HeapIterationScope iteration(thread);
        ObjectCounter counter(isolate_->group(), &smi);
        // Ensure that our particular zone is visited.
        iteration.IterateStackPointers(&counter,
                                       ValidationPolicy::kValidateFrames);
        EXPECT_EQ(1, counter.count());
      }
      char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_);
      String& unique_str = String::Handle(zone);
      {
        // String::New may create additional handles in the topmost scope that
        // we don't want to count, so wrap this in its own scope.
        HANDLESCOPE(thread);
        unique_str = String::New(unique_chars, Heap::kOld);
      }
      EXPECT(unique_str.Equals(unique_chars));
      {
        HeapIterationScope iteration(thread);
        ObjectCounter str_counter(isolate_->group(), &unique_str);
        // Ensure that our particular zone is visited.
        iteration.IterateStackPointers(&str_counter,
                                       ValidationPolicy::kValidateFrames);
        // We should visit the string object exactly once.
        EXPECT_EQ(1, str_counter.count());
      }
    }
    Thread::ExitIsolateAsHelper();
    {
      MonitorLocker ml(monitor_);
      *done_ = true;
      ml.Notify();
    }
  }

 private:
  Isolate* isolate_;
  Monitor* monitor_;
  bool* done_;
  intptr_t id_;
};

ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) {
  const int kTaskCount = 100;
  Monitor sync[kTaskCount];
  bool done[kTaskCount];
  Isolate* isolate = thread->isolate();
  for (int i = 0; i < kTaskCount; i++) {
    done[i] = false;
    Dart::thread_pool()->Run<TaskWithZoneAllocation>(isolate, &sync[i],
                                                     &done[i], i);
  }
  bool in_isolate = true;
  for (int i = 0; i < kTaskCount; i++) {
    // Check that main mutator thread can still freely use its own zone.
    String& bar = String::Handle(String::New("bar"));
    if (i % 10 == 0) {
      // Mutator thread is free to independently move in/out/between isolates.
      Thread::ExitIsolate();
      in_isolate = false;
    }
    MonitorLocker ml(&sync[i]);
    while (!done[i]) {
      if (in_isolate) {
        ml.WaitWithSafepointCheck(thread);
      } else {
        ml.Wait();
      }
    }
    EXPECT(done[i]);
    if (i % 10 == 0) {
      Thread::EnterIsolate(isolate);
      in_isolate = true;
    }
    EXPECT(bar.Equals("bar"));
  }
}

#ifndef PRODUCT
class SimpleTaskWithZoneAllocation : public ThreadPool::Task {
 public:
  SimpleTaskWithZoneAllocation(intptr_t id,
                               Isolate* isolate,
                               Thread** thread_ptr,
                               Monitor* sync,
                               Monitor* monitor,
                               intptr_t* done_count,
                               bool* wait)
      : id_(id),
        isolate_(isolate),
        thread_ptr_(thread_ptr),
        sync_(sync),
        monitor_(monitor),
        done_count_(done_count),
        wait_(wait) {}

  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
    {
      Thread* thread = Thread::Current();
      *thread_ptr_ = thread;
      CreateStackZones(id_);
    }
    Thread::ExitIsolateAsHelper();
    // Notify the main thread that this thread has exited.
    {
      MonitorLocker ml(monitor_);
      *done_count_ += 1;
      ml.Notify();
    }
  }

 private:
  void CreateStackZones(intptr_t num) {
    Thread* thread = Thread::Current();
    *thread_ptr_ = thread;

    StackZone stack_zone(thread);
    HANDLESCOPE(thread);
    Zone* zone = thread->zone();
    EXPECT_EQ(zone, stack_zone.GetZone());

    // Create a zone (which is also a stack resource) and exercise it a bit.
    ZoneGrowableArray<bool>* a0 = new (zone) ZoneGrowableArray<bool>(zone, 1);
    GrowableArray<bool> a1(zone, 1);
    for (intptr_t i = 0; i < 1000 * num + id_; ++i) {
      a0->Add(true);
      a1.Add(true);
    }

    num -= 1;
    if (num != 0) {
      CreateStackZones(num);
      return;
    }
    {
      // Let the main thread know we're done with memory ops on this thread.
      MonitorLocker ml(monitor_);
      *done_count_ += 1;
      ml.Notify();
    }
    // Wait for the go-ahead from the main thread to exit.
    {
      MonitorLocker sync_ml(sync_);
      while (*wait_) {
        sync_ml.Wait();
      }
    }
  }

  intptr_t id_;
  Isolate* isolate_;
  Thread** thread_ptr_;
  Monitor* sync_;
  Monitor* monitor_;
  intptr_t* done_count_;
  bool* wait_;
};

ISOLATE_UNIT_TEST_CASE(ManySimpleTasksWithZones) {
  const int kTaskCount = 10;
  Monitor monitor;
  Monitor sync;
  Thread* threads[kTaskCount];
  Isolate* isolate = Thread::Current()->isolate();
  intptr_t done_count = 0;
  bool wait = true;

  EXPECT(isolate->group()->heap()->GrowthControlState());

  NoHeapGrowthControlScope no_heap_growth_scope;

  for (intptr_t i = 0; i < kTaskCount; i++) {
    Dart::thread_pool()->Run<SimpleTaskWithZoneAllocation>(
        (i + 1), isolate, &threads[i], &sync, &monitor, &done_count, &wait);
  }
  // Wait until all spawned tasks finish their memory operations.
  {
    MonitorLocker ml(&monitor);
    while (done_count < kTaskCount) {
      ml.Wait();
    }
    // Reset the done counter for use later.
    done_count = 0;
  }

  // Unblock the tasks so they can finish.
  {
    MonitorLocker sync_ml(&sync);
    wait = false;
    sync_ml.NotifyAll();
  }
  // Now wait for them all to exit before destroying the isolate.
  {
    MonitorLocker ml(&monitor);
    while (done_count < kTaskCount) {
      ml.Wait();
    }
  }
}
#endif

TEST_CASE(ThreadRegistry) {
  Isolate* orig = Thread::Current()->isolate();
  Zone* orig_zone = Thread::Current()->zone();
  char* orig_str = orig_zone->PrintToString("foo");
  Dart_ExitIsolate();
  // Create and enter a new isolate.
  TestCase::CreateTestIsolate();
  Zone* zone0 = Thread::Current()->zone();
  EXPECT(zone0 != orig_zone);
  Dart_ShutdownIsolate();
  // Create and enter yet another isolate.
  TestCase::CreateTestIsolate();
  {
    // Create a stack resource this time, and exercise it.
    TransitionNativeToVM transition(Thread::Current());
    StackZone stack_zone(Thread::Current());
    Zone* zone1 = Thread::Current()->zone();
    EXPECT(zone1 != zone0);
    EXPECT(zone1 != orig_zone);
  }
  Dart_ShutdownIsolate();
  Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig));
  // Original zone should be preserved.
  EXPECT_EQ(orig_zone, Thread::Current()->zone());
  EXPECT_STREQ("foo", orig_str);
}

// A helper thread that repeatedly reads ICData
class ICDataTestTask : public ThreadPool::Task {
 public:
  static const intptr_t kTaskCount;

  ICDataTestTask(Isolate* isolate,
                 const Array& ic_datas,
                 Monitor* monitor,
                 intptr_t* exited,
                 std::atomic<bool>* done)
      : isolate_(isolate),
        ic_datas_(ic_datas),
        len_(ic_datas.Length()),
        monitor_(monitor),
        exited_(exited),
        done_(done) {}

  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);

    Thread* thread = Thread::Current();

    {
      StackZone stack_zone(thread);
      HANDLESCOPE(thread);

      ICData& ic_data = ICData::Handle();
      Array& arr = Array::Handle();
      while (true) {
        for (intptr_t cnt = 0; cnt < 0x1000; cnt++) {
          for (intptr_t i = 0; i < len_; i++) {
            ic_data ^= ic_datas_.AtAcquire(i);
            arr = ic_data.entries();
            intptr_t num_checks = arr.Length() / 3;
            if (num_checks < 0 || num_checks > 5) {
              OS::PrintErr("Failure: %" Pd " checks!\n", num_checks);
              abort();
            }
          }
        }

        if (done_->load(std::memory_order_acquire)) {
          break;
        }

        TransitionVMToBlocked blocked(thread);
      }
    }

    Thread::ExitIsolateAsHelper();
    {
      MonitorLocker ml(monitor_);
      ++*exited_;
      ml.Notify();
    }
  }

 private:
  Isolate* isolate_;
  const Array& ic_datas_;
  const intptr_t len_;
  Monitor* monitor_;
  intptr_t* exited_;  // # tasks that are no longer running.
  std::atomic<bool>* done_;  // Signal that helper threads can stop working.
};

static Function* CreateFunction(const char* name) {
  const String& class_name =
      String::Handle(Symbols::New(Thread::Current(), "ownerClass"));
  const Script& script = Script::Handle();
  const Library& lib = Library::Handle(Library::New(class_name));
  const Class& owner_class = Class::Handle(
      Class::New(lib, class_name, script, TokenPosition::kNoSource));
  const String& function_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), name));
  const FunctionType& signature = FunctionType::ZoneHandle(FunctionType::New());
  Function& function = Function::ZoneHandle(Function::New(
      signature, function_name, UntaggedFunction::kRegularFunction, true, false,
      false, false, false, owner_class, TokenPosition::kNoSource));
  return &function;
}

const intptr_t ICDataTestTask::kTaskCount = 1;

// Test that checks that other threads only see a fully initialized ICData
// whenever ICData is updated.
ISOLATE_UNIT_TEST_CASE(ICDataTest) {
  Isolate* isolate = thread->isolate();
  USE(isolate);
  Monitor monitor;
  intptr_t exited = 0;
  std::atomic<bool> done = {false};

  const intptr_t kNumICData = 0x10;

  const Array& ic_datas = Array::Handle(Array::New(kNumICData));
  ICData& ic_data = ICData::Handle();
  Function& owner = *CreateFunction("DummyFunction");
  String& name = String::Handle(String::New("foo"));
  const Array& args_desc =
      Array::Handle(ArgumentsDescriptor::NewBoxed(0, 0, Object::empty_array()));
  for (intptr_t i = 0; i < kNumICData; i++) {
    ic_data = ICData::New(owner, name, args_desc, /*deopt_id=*/0,
                          /*num_args_tested=*/1, ICData::kInstance,
                          Object::null_abstract_type());
    ic_datas.SetAtRelease(i, ic_data);
  }

  for (int i = 0; i < ICDataTestTask::kTaskCount; i++) {
    Dart::thread_pool()->Run<ICDataTestTask>(isolate, ic_datas, &monitor,
                                             &exited, &done);
  }

  for (int i = 0; i < 0x10000; i++) {
    for (intptr_t i = 0; i < kNumICData; i++) {
      ic_data ^= ic_datas.At(i);
      if (ic_data.NumberOfChecks() < 4) {
        ic_data.AddReceiverCheck(kInstanceCid + ic_data.NumberOfChecks(), owner,
                                 1);
      } else {
        ic_data = ICData::New(owner, name, args_desc, /*deopt_id=*/0,
                              /*num_args_tested=*/1, ICData::kInstance,
                              Object::null_abstract_type());
        ic_datas.SetAtRelease(i, ic_data);
      }
    }
  }
  // Ensure we looped long enough to allow all helpers to succeed and exit.
  {
    done.store(true, std::memory_order_release);
    MonitorLocker ml(&monitor);
    while (exited != ICDataTestTask::kTaskCount) {
      ml.Wait();
    }
    EXPECT_EQ(ICDataTestTask::kTaskCount, exited);
  }
}

// A helper thread that alternatingly cooperates and organizes
// safepoint rendezvous. At rendezvous, it explicitly visits the
// stacks looking for a specific marker (Smi) to verify that the expected
// number threads are actually visited. The task is "done" when it has
// successfully made all other tasks and the main thread rendezvous (may
// not happen in the first rendezvous, since tasks are still starting up).
class SafepointTestTask : public ThreadPool::Task {
 public:
  static const intptr_t kTaskCount;

  SafepointTestTask(Isolate* isolate,
                    Monitor* monitor,
                    intptr_t* expected_count,
                    intptr_t* total_done,
                    intptr_t* exited)
      : isolate_(isolate),
        monitor_(monitor),
        expected_count_(expected_count),
        total_done_(total_done),
        exited_(exited),
        local_done_(false) {}

  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
    {
      MonitorLocker ml(monitor_);
      ++*expected_count_;
    }
    Thread* thread = Thread::Current();
    for (int i = reinterpret_cast<intptr_t>(thread);; ++i) {
      StackZone stack_zone(thread);
      Zone* zone = thread->zone();
      HANDLESCOPE(thread);
      const intptr_t kUniqueSmi = 928327281;
      Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi));
      if ((i % 100) != 0) {
        // Usually, we just cooperate.
        TransitionVMToBlocked transition(thread);
      } else {
        // But occasionally, organize a rendezvous.
        HeapIterationScope iteration(thread);  // Establishes a safepoint.
        ASSERT(thread->IsAtSafepoint());
        ObjectCounter counter(isolate_->group(), &smi);
        iteration.IterateStackPointers(&counter,
                                       ValidationPolicy::kValidateFrames);
        {
          MonitorLocker ml(monitor_);
          EXPECT_EQ(*expected_count_, counter.count());
        }
        UserTag& tag = UserTag::Handle(zone, isolate_->current_tag());
        if (tag.ptr() != isolate_->default_tag()) {
          String& label = String::Handle(zone, tag.label());
          EXPECT(label.Equals("foo"));
          MonitorLocker ml(monitor_);
          if (*expected_count_ == kTaskCount && !local_done_) {
            // Success for the first time! Remember that we are done, and
            // update the total count.
            local_done_ = true;
            ++*total_done_;
          }
        }
      }
      // Check whether everyone is done.
      {
        MonitorLocker ml(monitor_);
        if (*total_done_ == kTaskCount) {
          // Another task might be at SafepointThreads when resuming. Ensure its
          // expectation reflects reality, since we pop our handles here.
          --*expected_count_;
          break;
        }
      }
    }
    Thread::ExitIsolateAsHelper();
    {
      MonitorLocker ml(monitor_);
      ++*exited_;
      ml.Notify();
    }
  }

 private:
  Isolate* isolate_;
  Monitor* monitor_;
  intptr_t* expected_count_;  // # copies of kUniqueSmi we expect to visit.
  intptr_t* total_done_;      // # tasks that successfully safepointed once.
  intptr_t* exited_;          // # tasks that are no longer running.
  bool local_done_;           // this task has successfully safepointed >= once.
};

const intptr_t SafepointTestTask::kTaskCount = 5;

// Test rendezvous of:
// - helpers in VM code,
// - main thread in pure Dart,
// organized by
// - helpers.
TEST_CASE(SafepointTestDart) {
  Isolate* isolate = Thread::Current()->isolate();
  Monitor monitor;
  intptr_t expected_count = 0;
  intptr_t total_done = 0;
  intptr_t exited = 0;
  for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
    Dart::thread_pool()->Run<SafepointTestTask>(
        isolate, &monitor, &expected_count, &total_done, &exited);
  }
// Run Dart code on the main thread long enough to allow all helpers
// to get their verification done and exit. Use a specific UserTag
// to enable the helpers to verify that the main thread is
// successfully interrupted in the pure Dart loop.
#if defined(USING_SIMULATOR)
  const intptr_t kLoopCount = 12345678;
#else
  const intptr_t kLoopCount = 1234567890;
#endif  // defined(USING_SIMULATOR)
  char buffer[1024];
  Utils::SNPrint(buffer, sizeof(buffer),
                 "import 'dart:developer';\n"
                 "int dummy = 0;\n"
                 "main() {\n"
                 "  new UserTag('foo').makeCurrent();\n"
                 "  for (dummy = 0; dummy < %" Pd
                 "; ++dummy) {\n"
                 "    dummy += (dummy & 1);\n"
                 "  }\n"
                 "}\n",
                 kLoopCount);
  Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
  EXPECT_VALID(lib);
  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
  EXPECT_VALID(result);
  // Ensure we looped long enough to allow all helpers to succeed and exit.
  {
    MonitorLocker ml(&monitor);
    while (exited != SafepointTestTask::kTaskCount) {
      ml.Wait();
    }
    EXPECT_EQ(SafepointTestTask::kTaskCount, total_done);
    EXPECT_EQ(SafepointTestTask::kTaskCount, exited);
  }
}

// Test rendezvous of:
// - helpers in VM code, and
// - main thread in VM code,
// organized by
// - helpers.
ISOLATE_UNIT_TEST_CASE(SafepointTestVM) {
  Isolate* isolate = thread->isolate();
  Monitor monitor;
  intptr_t expected_count = 0;
  intptr_t total_done = 0;
  intptr_t exited = 0;
  for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
    Dart::thread_pool()->Run<SafepointTestTask>(
        isolate, &monitor, &expected_count, &total_done, &exited);
  }
  String& label = String::Handle(String::New("foo"));
  UserTag& tag = UserTag::Handle(UserTag::New(label));
  isolate->set_current_tag(tag);
  MonitorLocker ml(&monitor);
  while (exited != SafepointTestTask::kTaskCount) {
    ml.WaitWithSafepointCheck(thread);
  }
}

// Test case for recursive safepoint operations.
ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest1) {
  intptr_t count = 0;
  {
    SafepointOperationScope safepoint_scope(thread);
    count += 1;
    {
      SafepointOperationScope safepoint_scope(thread);
      count += 1;
      {
        SafepointOperationScope safepoint_scope(thread);
        count += 1;
      }
    }
  }
  EXPECT(count == 3);
}

ISOLATE_UNIT_TEST_CASE(ThreadIterator_Count) {
  intptr_t thread_count_0 = 0;
  intptr_t thread_count_1 = 0;

  {
    OSThreadIterator ti;
    while (ti.HasNext()) {
      OSThread* thread = ti.Next();
      EXPECT(thread != NULL);
      thread_count_0++;
    }
  }

  {
    OSThreadIterator ti;
    while (ti.HasNext()) {
      OSThread* thread = ti.Next();
      EXPECT(thread != NULL);
      thread_count_1++;
    }
  }

  EXPECT(thread_count_0 > 0);
  EXPECT(thread_count_1 > 0);
  EXPECT(thread_count_0 >= thread_count_1);
}

ISOLATE_UNIT_TEST_CASE(ThreadIterator_FindSelf) {
  OSThread* current = OSThread::Current();
  EXPECT(OSThread::IsThreadInList(current->id()));
}

struct ThreadIteratorTestParams {
  ThreadId spawned_thread_id;
  ThreadJoinId spawned_thread_join_id;
  Monitor* monitor;
};

void ThreadIteratorTestMain(uword parameter) {
  ThreadIteratorTestParams* params =
      reinterpret_cast<ThreadIteratorTestParams*>(parameter);
  OSThread* thread = OSThread::Current();
  EXPECT(thread != NULL);

  MonitorLocker ml(params->monitor);
  params->spawned_thread_id = thread->id();
  params->spawned_thread_join_id = OSThread::GetCurrentThreadJoinId(thread);
  EXPECT(params->spawned_thread_id != OSThread::kInvalidThreadId);
  EXPECT(OSThread::IsThreadInList(thread->id()));
  ml.Notify();
}

// NOTE: This test case also verifies that known TLS destructors are called
// on Windows. See |OnDartThreadExit| in os_thread_win.cc for more details.
TEST_CASE(ThreadIterator_AddFindRemove) {
  ThreadIteratorTestParams params;
  params.spawned_thread_id = OSThread::kInvalidThreadId;
  params.monitor = new Monitor();

  {
    MonitorLocker ml(params.monitor);
    EXPECT(params.spawned_thread_id == OSThread::kInvalidThreadId);
    // Spawn thread and wait to receive the thread id.
    OSThread::Start("ThreadIteratorTest", ThreadIteratorTestMain,
                    reinterpret_cast<uword>(&params));
    while (params.spawned_thread_id == OSThread::kInvalidThreadId) {
      ml.Wait();
    }
    EXPECT(params.spawned_thread_id != OSThread::kInvalidThreadId);
    EXPECT(params.spawned_thread_join_id != OSThread::kInvalidThreadJoinId);
    OSThread::Join(params.spawned_thread_join_id);
  }

  EXPECT(!OSThread::IsThreadInList(params.spawned_thread_id))

  delete params.monitor;
}

// Test rendezvous of:
// - helpers in VM code, and
// - main thread in VM code,
// organized by
// - main thread, and
// - helpers.
ISOLATE_UNIT_TEST_CASE(SafepointTestVM2) {
  Isolate* isolate = thread->isolate();
  Monitor monitor;
  intptr_t expected_count = 0;
  intptr_t total_done = 0;
  intptr_t exited = 0;
  for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
    Dart::thread_pool()->Run<SafepointTestTask>(
        isolate, &monitor, &expected_count, &total_done, &exited);
  }
  bool all_helpers = false;
  do {
    SafepointOperationScope safepoint_scope(thread);
    {
      MonitorLocker ml(&monitor);
      if (expected_count == SafepointTestTask::kTaskCount) {
        all_helpers = true;
      }
    }
  } while (!all_helpers);
  String& label = String::Handle(String::New("foo"));
  UserTag& tag = UserTag::Handle(UserTag::New(label));
  isolate->set_current_tag(tag);
  MonitorLocker ml(&monitor);
  while (exited != SafepointTestTask::kTaskCount) {
    ml.WaitWithSafepointCheck(thread);
  }
}

// Test recursive safepoint operation scopes with other threads trying
// to also start a safepoint operation scope.
ISOLATE_UNIT_TEST_CASE(RecursiveSafepointTest2) {
  Isolate* isolate = thread->isolate();
  Monitor monitor;
  intptr_t expected_count = 0;
  intptr_t total_done = 0;
  intptr_t exited = 0;
  for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
    Dart::thread_pool()->Run<SafepointTestTask>(
        isolate, &monitor, &expected_count, &total_done, &exited);
  }
  bool all_helpers = false;
  do {
    SafepointOperationScope safepoint_scope(thread);
    {
      SafepointOperationScope safepoint_scope(thread);
      MonitorLocker ml(&monitor);
      if (expected_count == SafepointTestTask::kTaskCount) {
        all_helpers = true;
      }
    }
  } while (!all_helpers);
  String& label = String::Handle(String::New("foo"));
  UserTag& tag = UserTag::Handle(UserTag::New(label));
  isolate->set_current_tag(tag);
  bool all_exited = false;
  do {
    SafepointOperationScope safepoint_scope(thread);
    {
      SafepointOperationScope safepoint_scope(thread);
      MonitorLocker ml(&monitor);
      if (exited == SafepointTestTask::kTaskCount) {
        all_exited = true;
      }
    }
  } while (!all_exited);
}

class AllocAndGCTask : public ThreadPool::Task {
 public:
  AllocAndGCTask(Isolate* isolate, Monitor* done_monitor, bool* done)
      : isolate_(isolate), done_monitor_(done_monitor), done_(done) {}

  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
    {
      Thread* thread = Thread::Current();
      StackZone stack_zone(thread);
      Zone* zone = stack_zone.GetZone();
      HANDLESCOPE(thread);
      String& old_str = String::Handle(zone, String::New("old", Heap::kOld));
      isolate_->group()->heap()->CollectAllGarbage();
      EXPECT(old_str.Equals("old"));
    }
    Thread::ExitIsolateAsHelper();
    // Tell main thread that we are ready.
    {
      MonitorLocker ml(done_monitor_);
      ASSERT(!*done_);
      *done_ = true;
      ml.Notify();
    }
  }

 private:
  Isolate* isolate_;
  Monitor* done_monitor_;
  bool* done_;
};

ISOLATE_UNIT_TEST_CASE(HelperAllocAndGC) {
  Monitor done_monitor;
  bool done = false;
  Isolate* isolate = thread->isolate();
  Dart::thread_pool()->Run<AllocAndGCTask>(isolate, &done_monitor, &done);
  {
    while (true) {
      TransitionVMToBlocked transition(thread);
      MonitorLocker ml(&done_monitor);
      if (done) {
        break;
      }
    }
  }
}

class AllocateGlobsOfMemoryTask : public ThreadPool::Task {
 public:
  AllocateGlobsOfMemoryTask(Isolate* isolate, Monitor* done_monitor, bool* done)
      : isolate_(isolate), done_monitor_(done_monitor), done_(done) {}

  virtual void Run() {
    Thread::EnterIsolateAsHelper(isolate_, Thread::kUnknownTask);
    {
      Thread* thread = Thread::Current();
      StackZone stack_zone(thread);
      Zone* zone = stack_zone.GetZone();
      HANDLESCOPE(thread);
      int count = 100 * 1000;
      while (count-- > 0) {
        String::Handle(zone, String::New("abc"));
      }
    }
    Thread::ExitIsolateAsHelper();
    // Tell main thread that we are ready.
    {
      MonitorLocker ml(done_monitor_);
      ASSERT(!*done_);
      *done_ = true;
      ml.Notify();
    }
  }

 private:
  Isolate* isolate_;
  Monitor* done_monitor_;
  bool* done_;
};

ISOLATE_UNIT_TEST_CASE(ExerciseTLABs) {
  const int NUMBER_TEST_THREADS = 10;
  Monitor done_monitor[NUMBER_TEST_THREADS];
  bool done[NUMBER_TEST_THREADS];
  Isolate* isolate = thread->isolate();
  for (int i = 0; i < NUMBER_TEST_THREADS; i++) {
    done[i] = false;
    Dart::thread_pool()->Run<AllocateGlobsOfMemoryTask>(
        isolate, &done_monitor[i], &done[i]);
  }

  for (int i = 0; i < NUMBER_TEST_THREADS; i++) {
    MonitorLocker ml(&done_monitor[i]);
    while (!done[i]) {
      ml.WaitWithSafepointCheck(thread);
    }
  }
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockWithReadLock) {
  SafepointRwLock lock;
  SafepointReadRwLocker locker(Thread::Current(), &lock);
  DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
  EXPECT(!lock.IsCurrentThreadWriter());
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockWithWriteLock) {
  SafepointRwLock lock;
  SafepointWriteRwLocker locker(Thread::Current(), &lock);
  DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
  EXPECT(lock.IsCurrentThreadWriter());
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockWithoutAnyLocks) {
  SafepointRwLock lock;
  DEBUG_ONLY(EXPECT(!lock.IsCurrentThreadReader()));
  EXPECT(!lock.IsCurrentThreadWriter());
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockReentrantReadLock) {
  SafepointRwLock lock;
  {
    SafepointReadRwLocker locker(Thread::Current(), &lock);
    {
      SafepointReadRwLocker locker1(Thread::Current(), &lock);
      DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
      EXPECT(!lock.IsCurrentThreadWriter());
    }
    DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
    EXPECT(!lock.IsCurrentThreadWriter());
  }
  DEBUG_ONLY(EXPECT(!lock.IsCurrentThreadReader()));
  EXPECT(!lock.IsCurrentThreadWriter());
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockReentrantWriteLock) {
  SafepointRwLock lock;
  {
    SafepointWriteRwLocker locker(Thread::Current(), &lock);
    {
      SafepointWriteRwLocker locker1(Thread::Current(), &lock);
      DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
      EXPECT(lock.IsCurrentThreadWriter());
    }
    DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
    EXPECT(lock.IsCurrentThreadWriter());
  }
  DEBUG_ONLY(EXPECT(!lock.IsCurrentThreadReader()));
  EXPECT(!lock.IsCurrentThreadWriter());
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockWriteToReadLock) {
  SafepointRwLock lock;
  {
    SafepointWriteRwLocker locker(Thread::Current(), &lock);
    {
      SafepointReadRwLocker locker1(Thread::Current(), &lock);
      DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
      EXPECT(lock.IsCurrentThreadWriter());
    }
    DEBUG_ONLY(EXPECT(lock.IsCurrentThreadReader()));
    EXPECT(lock.IsCurrentThreadWriter());
  }
  DEBUG_ONLY(EXPECT(!lock.IsCurrentThreadReader()));
  EXPECT(!lock.IsCurrentThreadWriter());
}

template <typename LockType, typename LockerType>
static void RunLockerWithLongJumpTest() {
  const intptr_t kNumIterations = 5;
  intptr_t execution_count = 0;
  intptr_t thrown_count = 0;
  LockType lock;
  for (intptr_t i = 0; i < kNumIterations; ++i) {
    LongJumpScope jump;
    if (setjmp(*jump.Set()) == 0) {
      LockerType locker(Thread::Current(), &lock);
      execution_count++;
      Thread::Current()->long_jump_base()->Jump(
          1, Object::background_compilation_error());
    } else {
      thrown_count++;
    }
  }
  EXPECT_EQ(kNumIterations, execution_count);
  EXPECT_EQ(kNumIterations, thrown_count);
}
ISOLATE_UNIT_TEST_CASE(SafepointRwLockWriteWithLongJmp) {
  RunLockerWithLongJumpTest<SafepointRwLock, SafepointWriteRwLocker>();
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockReadWithLongJmp) {
  RunLockerWithLongJumpTest<SafepointRwLock, SafepointReadRwLocker>();
}

ISOLATE_UNIT_TEST_CASE(SafepointMutexLockerWithLongJmp) {
  RunLockerWithLongJumpTest<Mutex, SafepointMutexLocker>();
}

struct ReaderThreadState {
  ThreadJoinId reader_id = OSThread::kInvalidThreadJoinId;
  SafepointRwLock* rw_lock = nullptr;
  IsolateGroup* isolate_group = nullptr;
  intptr_t elapsed_us = 0;
};

void Helper(uword arg) {
  auto state = reinterpret_cast<ReaderThreadState*>(arg);
  state->reader_id = OSThread::GetCurrentThreadJoinId(OSThread::Current());

  const bool kBypassSafepoint = false;
  Thread::EnterIsolateGroupAsHelper(state->isolate_group, Thread::kUnknownTask,
                                    kBypassSafepoint);
  {
    auto thread = Thread::Current();
    const auto before_us = OS::GetCurrentMonotonicMicros();
    intptr_t after_us = before_us;
    {
      SafepointReadRwLocker reader(thread, state->rw_lock);
      after_us = OS::GetCurrentMonotonicMicros();
    }
    state->elapsed_us = (after_us - before_us);
  }
  Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
}

ISOLATE_UNIT_TEST_CASE(SafepointRwLockExclusiveNestedWriter_Regress44000) {
  auto isolate_group = IsolateGroup::Current();

  SafepointRwLock lock;
  ReaderThreadState state;
  state.rw_lock = &lock;
  state.isolate_group = isolate_group;
  {
    // Hold one writer lock.
    SafepointWriteRwLocker locker(Thread::Current(), &lock);
    {
      // Hold another, nested, writer lock.
      SafepointWriteRwLocker locker2(Thread::Current(), &lock);

      // Start a thread, it will try to acquire read lock but it will have to
      // wait until we have exited both writer scopes.
      if (OSThread::Start("DartWorker", &Helper,
                          reinterpret_cast<uword>(&state)) != 0) {
        FATAL("Could not start worker thread");
      }
      // Give thread a little time to actually start running.
      OS::Sleep(20);

      OS::Sleep(500);
    }
    OS::Sleep(500);
  }
  // Join the other thread.
  OSThread::Join(state.reader_id);

  // Ensure the reader thread had to wait for around 1 second.
  EXPECT(state.elapsed_us > 2 * 500 * 1000);
}

}  // namespace dart
