// 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/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);
    // 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) {
    ASSERT(thread->api_top_scope() == NULL);
    ReturnToFreelistLocked(thread);
  }
}


void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                         bool validate_frames) {
  MonitorLocker ml(threads_lock());
  Thread* thread = active_list_;
  while (thread != NULL) {
    if (thread->zone() != NULL) {
      thread->zone()->VisitObjectPointers(visitor);
    }
    thread->VisitObjectPointers(visitor);
    // Iterate over all the stack frames and visit objects on the stack.
    StackFrameIterator frames_iterator(thread->top_exit_frame_info(),
                                       validate_frames);
    StackFrame* frame = frames_iterator.NextFrame();
    while (frame != NULL) {
      frame->VisitObjectPointers(visitor);
      frame = frames_iterator.NextFrame();
    }
    thread = thread->next_;
  }
}


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


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
