Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1595)

Unified Diff: runtime/vm/thread_registry.cc

Issue 1541073002: Implement safepointing of threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix-typo Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/thread_registry.h ('k') | runtime/vm/thread_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « runtime/vm/thread_registry.h ('k') | runtime/vm/thread_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698