// Copyright (c) 2015, 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_registry.h"

#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/lockers.h"

namespace dart {

ThreadRegistry::~ThreadRegistry() {
  // Go over the free thread list and delete the thread objects.
  {
    MonitorLocker ml(threads_lock());
    // At this point the active list should be empty.
    ASSERT(active_list_ == NULL);

    // The [mutator_thread_] is kept alive until the destruction of the isolate.
    mutator_thread_->isolate_ = nullptr;

    // We have cached the mutator thread, delete it.
    delete mutator_thread_;
    mutator_thread_ = NULL;
    // Now delete all the threads in the free list.
    while (free_list_ != NULL) {
      Thread* thread = free_list_;
      free_list_ = thread->next_;
      delete thread;
    }
  }

  // Delete monitor.
  delete threads_lock_;
}

// Gets a free Thread structure, we special case the mutator thread
// by reusing the cached structure, see comment in 'thread_registry.h'.
Thread* ThreadRegistry::GetFreeThreadLocked(Isolate* isolate, bool is_mutator) {
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  Thread* thread;
  if (is_mutator) {
    if (mutator_thread_ == NULL) {
      mutator_thread_ = GetFromFreelistLocked(isolate);
    }
    thread = mutator_thread_;
  } else {
    thread = GetFromFreelistLocked(isolate);
    ASSERT(thread->api_top_scope() == NULL);
  }
  // Now add this Thread to the active list for the isolate.
  AddToActiveListLocked(thread);
  return thread;
}

void ThreadRegistry::ReturnThreadLocked(bool is_mutator, Thread* thread) {
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  // Remove thread from the active list for the isolate.
  RemoveFromActiveListLocked(thread);
  if (!is_mutator) {
    ReturnToFreelistLocked(thread);
  }
}

void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                         ValidationPolicy validate_frames) {
  MonitorLocker ml(threads_lock());
  bool mutator_thread_visited = false;
  Thread* thread = active_list_;
  while (thread != NULL) {
    thread->VisitObjectPointers(visitor, validate_frames);
    if (mutator_thread_ == thread) {
      mutator_thread_visited = true;
    }
    thread = thread->next_;
  }
  // Visit mutator thread even if it is not in the active list because of
  // api handles.
  if (!mutator_thread_visited && (mutator_thread_ != NULL)) {
    mutator_thread_->VisitObjectPointers(visitor, validate_frames);
  }
}

void ThreadRegistry::ReleaseStoreBuffers() {
  MonitorLocker ml(threads_lock());
  Thread* thread = active_list_;
  while (thread != NULL) {
    if (!thread->BypassSafepoints()) {
      thread->ReleaseStoreBuffer();
    }
    thread = thread->next_;
  }
}

void ThreadRegistry::AcquireMarkingStacks() {
  MonitorLocker ml(threads_lock());
  Thread* thread = active_list_;
  while (thread != NULL) {
    if (!thread->BypassSafepoints()) {
      thread->MarkingStackAcquire();
    }
    thread = thread->next_;
  }
}

void ThreadRegistry::ReleaseMarkingStacks() {
  MonitorLocker ml(threads_lock());
  Thread* thread = active_list_;
  while (thread != NULL) {
    if (!thread->BypassSafepoints()) {
      thread->MarkingStackRelease();
    }
    thread = thread->next_;
  }
}

#ifndef PRODUCT
void ThreadRegistry::PrintJSON(JSONStream* stream) const {
  MonitorLocker ml(threads_lock());
  JSONArray threads(stream);
  Thread* current = active_list_;
  while (current != NULL) {
    threads.AddValue(current);
    current = current->next_;
  }
}
#endif

intptr_t ThreadRegistry::CountZoneHandles() const {
  MonitorLocker ml(threads_lock());
  intptr_t count = 0;
  Thread* current = active_list_;
  while (current != NULL) {
    count += current->CountZoneHandles();
    current = current->next_;
  }
  return count;
}

intptr_t ThreadRegistry::CountScopedHandles() const {
  MonitorLocker ml(threads_lock());
  intptr_t count = 0;
  Thread* current = active_list_;
  while (current != NULL) {
    count += current->CountScopedHandles();
    current = current->next_;
  }
  return count;
}

void ThreadRegistry::AddToActiveListLocked(Thread* thread) {
  ASSERT(thread != NULL);
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  thread->next_ = active_list_;
  active_list_ = thread;
}

void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) {
  ASSERT(thread != NULL);
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  Thread* prev = NULL;
  Thread* current = active_list_;
  while (current != NULL) {
    if (current == thread) {
      if (prev == NULL) {
        active_list_ = current->next_;
      } else {
        prev->next_ = current->next_;
      }
      break;
    }
    prev = current;
    current = current->next_;
  }
}

Thread* ThreadRegistry::GetFromFreelistLocked(Isolate* isolate) {
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  Thread* thread = NULL;
  // Get thread structure from free list or create a new one.
  if (free_list_ == NULL) {
    thread = new Thread(isolate);
  } else {
    thread = free_list_;
    free_list_ = thread->next_;
  }
  return thread;
}

void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) {
  ASSERT(thread != NULL);
  ASSERT(thread->os_thread_ == NULL);
  ASSERT(thread->isolate_ == NULL);
  ASSERT(thread->heap_ == NULL);
  ASSERT(threads_lock()->IsOwnedByCurrentThread());
  // Add thread to the free list.
  thread->next_ = free_list_;
  free_list_ = thread;
}

}  // namespace dart
