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 |