| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/thread_registry.h" | 5 #include "vm/thread_registry.h" |
| 6 | 6 |
| 7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| 11 | 11 |
| 12 ThreadRegistry::~ThreadRegistry() { | 12 ThreadRegistry::~ThreadRegistry() { |
| 13 // Go over the free thread list and delete the thread objects. | 13 // Go over the free thread list and delete the thread objects. |
| 14 { | 14 { |
| 15 MonitorLocker ml(monitor_); | 15 MonitorLocker ml(monitor_); |
| 16 // At this point the mutator thread should be the only thread | 16 // At this point the active list should be empty. |
| 17 // in the active list, delete it. | 17 ASSERT(active_list_ == NULL); |
| 18 ASSERT(active_list_->next_ == NULL); | 18 // We have cached the mutator thread, delete it. |
| 19 ASSERT(active_list_ == mutator_thread_); | |
| 20 delete mutator_thread_; | 19 delete mutator_thread_; |
| 21 active_list_ = NULL; | |
| 22 mutator_thread_ = NULL; | 20 mutator_thread_ = NULL; |
| 23 // Now delete all the threads in the free list. | 21 // Now delete all the threads in the free list. |
| 24 while (free_list_ != NULL) { | 22 while (free_list_ != NULL) { |
| 25 Thread* thread = free_list_; | 23 Thread* thread = free_list_; |
| 26 free_list_ = thread->next_; | 24 free_list_ = thread->next_; |
| 27 delete thread; | 25 delete thread; |
| 28 } | 26 } |
| 29 } | 27 } |
| 30 | 28 |
| 31 // Delete monitor. | 29 // Delete monitor. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 bool bypass_safepoint) { | 71 bool bypass_safepoint) { |
| 74 MonitorLocker ml(monitor_); | 72 MonitorLocker ml(monitor_); |
| 75 // Wait for any rendezvous in progress. | 73 // Wait for any rendezvous in progress. |
| 76 while (!bypass_safepoint && in_rendezvous_) { | 74 while (!bypass_safepoint && in_rendezvous_) { |
| 77 ml.Wait(Monitor::kNoTimeout); | 75 ml.Wait(Monitor::kNoTimeout); |
| 78 } | 76 } |
| 79 Thread* thread = NULL; | 77 Thread* thread = NULL; |
| 80 OSThread* os_thread = OSThread::Current(); | 78 OSThread* os_thread = OSThread::Current(); |
| 81 ASSERT(os_thread != NULL); | 79 ASSERT(os_thread != NULL); |
| 82 ASSERT(isolate->heap() != NULL); | 80 ASSERT(isolate->heap() != NULL); |
| 81 // First get a Thread structure. (we special case the mutator thread |
| 82 // by reusing the cached structure, see comment in 'thread_registry.h'). |
| 83 if (is_mutator) { | 83 if (is_mutator) { |
| 84 if (mutator_thread_ == NULL) { | 84 if (mutator_thread_ == NULL) { |
| 85 mutator_thread_ = GetThreadFromFreelist(isolate); | 85 mutator_thread_ = GetThreadFromFreelist(isolate); |
| 86 } | 86 } |
| 87 thread = mutator_thread_; | 87 thread = mutator_thread_; |
| 88 } else { | 88 } else { |
| 89 thread = GetThreadFromFreelist(isolate); | 89 thread = GetThreadFromFreelist(isolate); |
| 90 ASSERT(thread->api_top_scope() == NULL); | 90 ASSERT(thread->api_top_scope() == NULL); |
| 91 } | 91 } |
| 92 // Now add this Thread to the active list for the isolate. |
| 93 AddThreadToActiveList(thread); |
| 94 // Set up other values and set the TLS value. |
| 92 thread->isolate_ = isolate; | 95 thread->isolate_ = isolate; |
| 93 thread->heap_ = isolate->heap(); | 96 thread->heap_ = isolate->heap(); |
| 94 thread->set_os_thread(os_thread); | 97 thread->set_os_thread(os_thread); |
| 95 os_thread->set_thread(thread); | 98 os_thread->set_thread(thread); |
| 96 Thread::SetCurrent(thread); | 99 Thread::SetCurrent(thread); |
| 97 os_thread->EnableThreadInterrupts(); | 100 os_thread->EnableThreadInterrupts(); |
| 98 return thread; | 101 return thread; |
| 99 } | 102 } |
| 100 | 103 |
| 101 | 104 |
| 102 void ThreadRegistry::Unschedule(Thread* thread, | 105 void ThreadRegistry::Unschedule(Thread* thread, |
| 103 bool is_mutator, | 106 bool is_mutator, |
| 104 bool bypass_safepoint) { | 107 bool bypass_safepoint) { |
| 105 MonitorLocker ml(monitor_); | 108 MonitorLocker ml(monitor_); |
| 106 OSThread* os_thread = thread->os_thread(); | 109 OSThread* os_thread = thread->os_thread(); |
| 107 ASSERT(os_thread != NULL); | 110 ASSERT(os_thread != NULL); |
| 108 os_thread->DisableThreadInterrupts(); | 111 os_thread->DisableThreadInterrupts(); |
| 109 os_thread->set_thread(NULL); | 112 os_thread->set_thread(NULL); |
| 110 OSThread::SetCurrent(os_thread); | 113 OSThread::SetCurrent(os_thread); |
| 111 thread->isolate_ = NULL; | 114 thread->isolate_ = NULL; |
| 112 thread->heap_ = NULL; | 115 thread->heap_ = NULL; |
| 113 thread->set_os_thread(NULL); | 116 thread->set_os_thread(NULL); |
| 117 // Remove thread from the active list for the isolate. |
| 118 RemoveThreadFromActiveList(thread); |
| 119 // Return thread to the free list (we special case the mutator |
| 120 // thread by holding on to it, see comment in 'thread_registry.h'). |
| 114 if (!is_mutator) { | 121 if (!is_mutator) { |
| 115 ASSERT(thread->api_top_scope() == NULL); | 122 ASSERT(thread->api_top_scope() == NULL); |
| 116 ReturnThreadToFreelist(thread); | 123 ReturnThreadToFreelist(thread); |
| 117 } | 124 } |
| 118 if (!bypass_safepoint && in_rendezvous_) { | 125 if (!bypass_safepoint && in_rendezvous_) { |
| 119 // Don't wait for this thread. | 126 // Don't wait for this thread. |
| 120 ASSERT(remaining_ > 0); | 127 ASSERT(remaining_ > 0); |
| 121 if (--remaining_ == 0) { | 128 if (--remaining_ == 0) { |
| 122 ml.NotifyAll(); | 129 ml.NotifyAll(); |
| 123 } | 130 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 140 StackFrame* frame = frames_iterator.NextFrame(); | 147 StackFrame* frame = frames_iterator.NextFrame(); |
| 141 while (frame != NULL) { | 148 while (frame != NULL) { |
| 142 frame->VisitObjectPointers(visitor); | 149 frame->VisitObjectPointers(visitor); |
| 143 frame = frames_iterator.NextFrame(); | 150 frame = frames_iterator.NextFrame(); |
| 144 } | 151 } |
| 145 thread = thread->next_; | 152 thread = thread->next_; |
| 146 } | 153 } |
| 147 } | 154 } |
| 148 | 155 |
| 149 | 156 |
| 150 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) { | 157 void ThreadRegistry::AddThreadToActiveList(Thread* thread) { |
| 158 ASSERT(thread != NULL); |
| 151 ASSERT(monitor_->IsOwnedByCurrentThread()); | 159 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 152 Thread* thread = NULL; | |
| 153 // Get thread structure from free list or create a new one. | |
| 154 if (free_list_ == NULL) { | |
| 155 thread = new Thread(isolate); | |
| 156 } else { | |
| 157 thread = free_list_; | |
| 158 free_list_ = thread->next_; | |
| 159 } | |
| 160 // Add thread to active list. | |
| 161 thread->next_ = active_list_; | 160 thread->next_ = active_list_; |
| 162 active_list_ = thread; | 161 active_list_ = thread; |
| 163 return thread; | |
| 164 } | 162 } |
| 165 | 163 |
| 166 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) { | 164 |
| 165 void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) { |
| 167 ASSERT(thread != NULL); | 166 ASSERT(thread != NULL); |
| 168 ASSERT(thread->os_thread_ == NULL); | |
| 169 ASSERT(thread->isolate_ == NULL); | |
| 170 ASSERT(thread->heap_ == NULL); | |
| 171 ASSERT(monitor_->IsOwnedByCurrentThread()); | 167 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 172 // First remove the thread from the active list. | |
| 173 Thread* prev = NULL; | 168 Thread* prev = NULL; |
| 174 Thread* current = active_list_; | 169 Thread* current = active_list_; |
| 175 while (current != NULL) { | 170 while (current != NULL) { |
| 176 if (current == thread) { | 171 if (current == thread) { |
| 177 if (prev == NULL) { | 172 if (prev == NULL) { |
| 178 active_list_ = current->next_; | 173 active_list_ = current->next_; |
| 179 } else { | 174 } else { |
| 180 prev->next_ = current->next_; | 175 prev->next_ = current->next_; |
| 181 } | 176 } |
| 182 break; | 177 break; |
| 183 } | 178 } |
| 184 prev = current; | 179 prev = current; |
| 185 current = current->next_; | 180 current = current->next_; |
| 186 } | 181 } |
| 187 // Now add thread to the free list. | 182 } |
| 183 |
| 184 |
| 185 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) { |
| 186 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 187 Thread* thread = NULL; |
| 188 // Get thread structure from free list or create a new one. |
| 189 if (free_list_ == NULL) { |
| 190 thread = new Thread(isolate); |
| 191 } else { |
| 192 thread = free_list_; |
| 193 free_list_ = thread->next_; |
| 194 } |
| 195 return thread; |
| 196 } |
| 197 |
| 198 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) { |
| 199 ASSERT(thread != NULL); |
| 200 ASSERT(thread->os_thread_ == NULL); |
| 201 ASSERT(thread->isolate_ == NULL); |
| 202 ASSERT(thread->heap_ == NULL); |
| 203 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 204 // Add thread to the free list. |
| 188 thread->next_ = free_list_; | 205 thread->next_ = free_list_; |
| 189 free_list_ = thread; | 206 free_list_ = thread; |
| 190 } | 207 } |
| 191 | 208 |
| 192 | 209 |
| 193 void ThreadRegistry::CheckSafepointLocked() { | 210 void ThreadRegistry::CheckSafepointLocked() { |
| 194 int64_t last_round = -1; | 211 int64_t last_round = -1; |
| 195 while (in_rendezvous_) { | 212 while (in_rendezvous_) { |
| 196 ASSERT(round_ >= last_round); | 213 ASSERT(round_ >= last_round); |
| 197 if (round_ != last_round) { | 214 if (round_ != last_round) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 220 intptr_t count = 0; | 237 intptr_t count = 0; |
| 221 Thread* current = active_list_; | 238 Thread* current = active_list_; |
| 222 while (current != NULL) { | 239 while (current != NULL) { |
| 223 ++count; | 240 ++count; |
| 224 current = current->next_; | 241 current = current->next_; |
| 225 } | 242 } |
| 226 return count; | 243 return count; |
| 227 } | 244 } |
| 228 | 245 |
| 229 } // namespace dart | 246 } // namespace dart |
| OLD | NEW |