// 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) {}

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

  void VisitCompressedPointers(uword heap_base,
                               CompressedObjectPtr* first,
                               CompressedObjectPtr* last) {
    for (CompressedObjectPtr* current = first; current <= last; ++current) {
      if (current->Decompress(heap_base) == 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;
  {
    GcSafepointOperationScope safepoint_scope(thread);
    count += 1;
    {
      GcSafepointOperationScope safepoint_scope(thread);
      count += 1;
      {
        GcSafepointOperationScope 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 {
    GcSafepointOperationScope 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 {
    GcSafepointOperationScope safepoint_scope(thread);
    {
      GcSafepointOperationScope 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 {
    GcSafepointOperationScope safepoint_scope(thread);
    {
      GcSafepointOperationScope 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;
  volatile intptr_t execution_count = 0;
  volatile 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);
}

ISOLATE_UNIT_TEST_CASE(SafepointMonitorUnlockScope) {
  // This test uses ASSERT instead of EXPECT because IsOwnedByCurrentThread is
  // only available in debug mode. Since our vm/cc tests run in DEBUG mode that
  // is sufficent for this test.
  Monitor monitor;
  {
    SafepointMonitorLocker ml(&monitor);
    ASSERT(monitor.IsOwnedByCurrentThread());
    {
      SafepointMonitorUnlockScope ml_unlocker(&ml);
      ASSERT(!monitor.IsOwnedByCurrentThread());
      {
        SafepointMonitorLocker inner_ml(&monitor);
        ASSERT(monitor.IsOwnedByCurrentThread());
      }
    }
  }
}

}  // namespace dart
