| Index: runtime/vm/thread_registry.cc
|
| diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
|
| index 2d2dee3f0357aa008b12f2beee6adf33ec663029..111ae57596f7cd3ddceca27cd9eb9cf1e0cf242d 100644
|
| --- a/runtime/vm/thread_registry.cc
|
| +++ b/runtime/vm/thread_registry.cc
|
| @@ -12,7 +12,7 @@ namespace dart {
|
| ThreadRegistry::~ThreadRegistry() {
|
| // Go over the free thread list and delete the thread objects.
|
| {
|
| - MonitorLocker ml(monitor_);
|
| + 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.
|
| @@ -27,114 +27,44 @@ ThreadRegistry::~ThreadRegistry() {
|
| }
|
|
|
| // Delete monitor.
|
| - delete monitor_;
|
| + delete threads_lock_;
|
| }
|
|
|
|
|
| -void ThreadRegistry::SafepointThreads() {
|
| - MonitorLocker ml(monitor_);
|
| - // First wait for any older rounds that are still in progress.
|
| - while (in_rendezvous_) {
|
| - // Assert we are not the organizer trying to nest calls to SafepointThreads.
|
| - ASSERT(remaining_ > 0);
|
| - CheckSafepointLocked();
|
| - }
|
| - // Start a new round.
|
| - in_rendezvous_ = true;
|
| - ++round_; // Overflows after 240+ years @ 10^9 safepoints per second.
|
| - remaining_ = CountScheduledLocked();
|
| - Isolate* isolate = Isolate::Current();
|
| - // We only expect this method to be called from within the isolate itself.
|
| - ASSERT(isolate->thread_registry() == this);
|
| - --remaining_; // Exclude this thread from the count.
|
| - // Ensure the main mutator will reach a safepoint (could be running Dart).
|
| - if (!Thread::Current()->IsMutatorThread()) {
|
| - isolate->ScheduleInterrupts(Isolate::kVMInterrupt);
|
| - }
|
| - while (remaining_ > 0) {
|
| - ml.Wait(Monitor::kNoTimeout);
|
| - }
|
| -}
|
| -
|
| -
|
| -void ThreadRegistry::ResumeAllThreads() {
|
| - MonitorLocker ml(monitor_);
|
| - ASSERT(in_rendezvous_);
|
| - in_rendezvous_ = false;
|
| - ml.NotifyAll();
|
| -}
|
| -
|
| -
|
| -Thread* ThreadRegistry::Schedule(Isolate* isolate,
|
| - bool is_mutator,
|
| - bool bypass_safepoint) {
|
| - MonitorLocker ml(monitor_);
|
| - // Wait for any rendezvous in progress.
|
| - while (!bypass_safepoint && in_rendezvous_) {
|
| - ml.Wait(Monitor::kNoTimeout);
|
| - }
|
| - Thread* thread = NULL;
|
| - OSThread* os_thread = OSThread::Current();
|
| - if (os_thread != NULL) {
|
| - ASSERT(isolate->heap() != NULL);
|
| - // First get a Thread structure. (we special case the mutator thread
|
| - // by reusing the cached structure, see comment in 'thread_registry.h').
|
| - if (is_mutator) {
|
| - if (mutator_thread_ == NULL) {
|
| - mutator_thread_ = GetThreadFromFreelist(isolate);
|
| - }
|
| - thread = mutator_thread_;
|
| - } else {
|
| - thread = GetThreadFromFreelist(isolate);
|
| - ASSERT(thread->api_top_scope() == NULL);
|
| +// 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);
|
| }
|
| - // Now add this Thread to the active list for the isolate.
|
| - AddThreadToActiveList(thread);
|
| - // Set up other values and set the TLS value.
|
| - thread->isolate_ = isolate;
|
| - thread->heap_ = isolate->heap();
|
| - thread->set_os_thread(os_thread);
|
| - os_thread->set_thread(thread);
|
| - Thread::SetCurrent(thread);
|
| - os_thread->EnableThreadInterrupts();
|
| + 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::Unschedule(Thread* thread,
|
| - bool is_mutator,
|
| - bool bypass_safepoint) {
|
| - MonitorLocker ml(monitor_);
|
| - OSThread* os_thread = thread->os_thread();
|
| - ASSERT(os_thread != NULL);
|
| - os_thread->DisableThreadInterrupts();
|
| - os_thread->set_thread(NULL);
|
| - OSThread::SetCurrent(os_thread);
|
| - thread->isolate_ = NULL;
|
| - thread->heap_ = NULL;
|
| - thread->set_os_thread(NULL);
|
| +void ThreadRegistry::ReturnThreadLocked(bool is_mutator, Thread* thread) {
|
| + ASSERT(threads_lock()->IsOwnedByCurrentThread());
|
| // Remove thread from the active list for the isolate.
|
| - RemoveThreadFromActiveList(thread);
|
| - // Return thread to the free list (we special case the mutator
|
| - // thread by holding on to it, see comment in 'thread_registry.h').
|
| + RemoveFromActiveListLocked(thread);
|
| if (!is_mutator) {
|
| ASSERT(thread->api_top_scope() == NULL);
|
| - ReturnThreadToFreelist(thread);
|
| - }
|
| - if (!bypass_safepoint && in_rendezvous_) {
|
| - // Don't wait for this thread.
|
| - ASSERT(remaining_ > 0);
|
| - if (--remaining_ == 0) {
|
| - ml.NotifyAll();
|
| - }
|
| + ReturnToFreelistLocked(thread);
|
| }
|
| }
|
|
|
|
|
| void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
|
| bool validate_frames) {
|
| - MonitorLocker ml(monitor_);
|
| + MonitorLocker ml(threads_lock());
|
| Thread* thread = active_list_;
|
| while (thread != NULL) {
|
| if (thread->zone() != NULL) {
|
| @@ -155,7 +85,7 @@ void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
|
|
|
|
|
| void ThreadRegistry::PrepareForGC() {
|
| - MonitorLocker ml(monitor_);
|
| + MonitorLocker ml(threads_lock());
|
| Thread* thread = active_list_;
|
| while (thread != NULL) {
|
| thread->PrepareForGC();
|
| @@ -164,17 +94,17 @@ void ThreadRegistry::PrepareForGC() {
|
| }
|
|
|
|
|
| -void ThreadRegistry::AddThreadToActiveList(Thread* thread) {
|
| +void ThreadRegistry::AddToActiveListLocked(Thread* thread) {
|
| ASSERT(thread != NULL);
|
| - ASSERT(monitor_->IsOwnedByCurrentThread());
|
| + ASSERT(threads_lock()->IsOwnedByCurrentThread());
|
| thread->next_ = active_list_;
|
| active_list_ = thread;
|
| }
|
|
|
|
|
| -void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) {
|
| +void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) {
|
| ASSERT(thread != NULL);
|
| - ASSERT(monitor_->IsOwnedByCurrentThread());
|
| + ASSERT(threads_lock()->IsOwnedByCurrentThread());
|
| Thread* prev = NULL;
|
| Thread* current = active_list_;
|
| while (current != NULL) {
|
| @@ -192,8 +122,8 @@ void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) {
|
| }
|
|
|
|
|
| -Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
|
| - ASSERT(monitor_->IsOwnedByCurrentThread());
|
| +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) {
|
| @@ -205,51 +135,15 @@ Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
|
| return thread;
|
| }
|
|
|
| -void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
|
| +void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) {
|
| ASSERT(thread != NULL);
|
| ASSERT(thread->os_thread_ == NULL);
|
| ASSERT(thread->isolate_ == NULL);
|
| ASSERT(thread->heap_ == NULL);
|
| - ASSERT(monitor_->IsOwnedByCurrentThread());
|
| + ASSERT(threads_lock()->IsOwnedByCurrentThread());
|
| // Add thread to the free list.
|
| thread->next_ = free_list_;
|
| free_list_ = thread;
|
| }
|
|
|
| -
|
| -void ThreadRegistry::CheckSafepointLocked() {
|
| - int64_t last_round = -1;
|
| - while (in_rendezvous_) {
|
| - ASSERT(round_ >= last_round);
|
| - if (round_ != last_round) {
|
| - ASSERT((last_round == -1) || (round_ == (last_round + 1)));
|
| - last_round = round_;
|
| - // Participate in this round.
|
| - if (--remaining_ == 0) {
|
| - // Ensure the organizing thread is notified.
|
| - // TODO(koda): Use separate condition variables and plain 'Notify'.
|
| - monitor_->NotifyAll();
|
| - }
|
| - }
|
| - monitor_->Wait(Monitor::kNoTimeout);
|
| - // Note: Here, round_ is needed to detect and distinguish two cases:
|
| - // a) The old rendezvous is still in progress, so just keep waiting, or
|
| - // b) after ResumeAllThreads, another call to SafepointThreads was
|
| - // made before this thread got a chance to reaquire monitor_, thus this
|
| - // thread should (again) decrease remaining_ to indicate cooperation in
|
| - // this new round.
|
| - }
|
| -}
|
| -
|
| -
|
| -intptr_t ThreadRegistry::CountScheduledLocked() {
|
| - intptr_t count = 0;
|
| - Thread* current = active_list_;
|
| - while (current != NULL) {
|
| - ++count;
|
| - current = current->next_;
|
| - }
|
| - return count;
|
| -}
|
| -
|
| } // namespace dart
|
|
|