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

Unified Diff: runtime/vm/thread_registry.cc

Issue 1439483003: - Add an OSThread structure which is the generic TLS structure for all C++ (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review Created 5 years, 1 month 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 f0f80e3fd08cab01d2c82715410765c1953df4aa..6031366895be857a0855147128a8516c55c818a5 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -10,6 +10,24 @@
namespace dart {
ThreadRegistry::~ThreadRegistry() {
+ // Go over the free thread list and delete the thread objects.
+ {
+ MonitorLocker ml(monitor_);
+ // At this point the mutator thread should be the only thread
+ // in the active list, delete it.
+ ASSERT(active_list_->next_ == NULL);
+ ASSERT(active_list_ == mutator_thread_);
+ delete mutator_thread_;
+ active_list_ = NULL;
+ 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 monitor_;
}
@@ -50,67 +68,123 @@ void ThreadRegistry::ResumeAllThreads() {
}
-void ThreadRegistry::PruneThread(Thread* thread) {
+Thread* ThreadRegistry::Schedule(Isolate* isolate,
+ bool is_mutator,
+ bool bypass_safepoint) {
MonitorLocker ml(monitor_);
- intptr_t length = entries_.length();
- if (length == 0) {
- return;
+ // Wait for any rendezvous in progress.
+ while (!bypass_safepoint && in_rendezvous_) {
+ ml.Wait(Monitor::kNoTimeout);
}
- intptr_t found_index = -1;
- for (intptr_t index = 0; index < length; index++) {
- if (entries_.At(index).thread == thread) {
- found_index = index;
- break;
+ Thread* thread = NULL;
+ OSThread* os_thread = OSThread::Current();
+ ASSERT(os_thread != NULL);
+ ASSERT(isolate->heap() != NULL);
+ if (is_mutator) {
+ if (mutator_thread_ == NULL) {
+ mutator_thread_ = GetThreadFromFreelist(isolate);
}
+ thread = mutator_thread_;
+ } else {
+ thread = GetThreadFromFreelist(isolate);
}
- if (found_index < 0) {
- return;
- }
- entries_.RemoveAt(found_index);
-}
-
-
-ThreadRegistry::EntryIterator::EntryIterator(ThreadRegistry* registry)
- : index_(0),
- registry_(NULL) {
- Reset(registry);
+ thread->isolate_ = isolate;
+ thread->heap_ = isolate->heap();
+ thread->set_os_thread(os_thread);
+ os_thread->set_thread(thread);
+ Thread::SetCurrent(thread);
+ os_thread->EnableThreadInterrupts();
+ return thread;
}
-ThreadRegistry::EntryIterator::~EntryIterator() {
- Reset(NULL);
-}
-
-
-void ThreadRegistry::EntryIterator::Reset(ThreadRegistry* registry) {
- // Reset index.
- index_ = 0;
-
- // Unlock old registry.
- if (registry_ != NULL) {
- registry_->monitor_->Exit();
+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();
+ thread->isolate_ = NULL;
+ thread->heap_ = NULL;
+ thread->set_os_thread(NULL);
+ os_thread->set_thread(NULL);
+ OSThread::SetCurrent(os_thread);
+ if (!is_mutator) {
+ ReturnThreadToFreelist(thread);
}
+ if (!bypass_safepoint && in_rendezvous_) {
+ // Don't wait for this thread.
+ ASSERT(remaining_ > 0);
+ if (--remaining_ == 0) {
+ ml.NotifyAll();
+ }
+ }
+}
- registry_ = registry;
- // Lock new registry.
- if (registry_ != NULL) {
- registry_->monitor_->Enter();
+void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
+ bool validate_frames) {
+ MonitorLocker ml(monitor_);
+ 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_;
}
}
-bool ThreadRegistry::EntryIterator::HasNext() const {
- if (registry_ == NULL) {
- return false;
+Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
+ ASSERT(monitor_->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 index_ < registry_->entries_.length();
+ // Add thread to active list.
+ thread->next_ = active_list_;
+ active_list_ = thread;
+ return thread;
}
-
-const ThreadRegistry::Entry& ThreadRegistry::EntryIterator::Next() {
- ASSERT(HasNext());
- return registry_->entries_.At(index_++);
+void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
+ ASSERT(thread != NULL);
+ ASSERT(thread->os_thread_ == NULL);
+ ASSERT(thread->isolate_ == NULL);
+ ASSERT(thread->heap_ == NULL);
+ ASSERT(monitor_->IsOwnedByCurrentThread());
+ // First remove the thread from the active list.
+ 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_;
+ }
+ // Now add thread to the free list.
+ thread->next_ = free_list_;
+ free_list_ = thread;
}
@@ -142,11 +216,10 @@ void ThreadRegistry::CheckSafepointLocked() {
intptr_t ThreadRegistry::CountScheduledLocked() {
intptr_t count = 0;
- for (int i = 0; i < entries_.length(); ++i) {
- const Entry& entry = entries_[i];
- if (entry.scheduled) {
- ++count;
- }
+ Thread* current = active_list_;
+ while (current != NULL) {
+ ++count;
+ current = current->next_;
}
return count;
}
« 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