| 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 { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 ASSERT(remaining_ > 0); | 39 ASSERT(remaining_ > 0); |
| 40 CheckSafepointLocked(); | 40 CheckSafepointLocked(); |
| 41 } | 41 } |
| 42 // Start a new round. | 42 // Start a new round. |
| 43 in_rendezvous_ = true; | 43 in_rendezvous_ = true; |
| 44 ++round_; // Overflows after 240+ years @ 10^9 safepoints per second. | 44 ++round_; // Overflows after 240+ years @ 10^9 safepoints per second. |
| 45 remaining_ = CountScheduledLocked(); | 45 remaining_ = CountScheduledLocked(); |
| 46 Isolate* isolate = Isolate::Current(); | 46 Isolate* isolate = Isolate::Current(); |
| 47 // We only expect this method to be called from within the isolate itself. | 47 // We only expect this method to be called from within the isolate itself. |
| 48 ASSERT(isolate->thread_registry() == this); | 48 ASSERT(isolate->thread_registry() == this); |
| 49 // TODO(koda): Rename Thread::PrepareForGC and call it here? | |
| 50 --remaining_; // Exclude this thread from the count. | 49 --remaining_; // Exclude this thread from the count. |
| 51 // Ensure the main mutator will reach a safepoint (could be running Dart). | 50 // Ensure the main mutator will reach a safepoint (could be running Dart). |
| 52 if (!Thread::Current()->IsMutatorThread()) { | 51 if (!Thread::Current()->IsMutatorThread()) { |
| 53 isolate->ScheduleInterrupts(Isolate::kVMInterrupt); | 52 isolate->ScheduleInterrupts(Isolate::kVMInterrupt); |
| 54 } | 53 } |
| 55 while (remaining_ > 0) { | 54 while (remaining_ > 0) { |
| 56 ml.Wait(Monitor::kNoTimeout); | 55 ml.Wait(Monitor::kNoTimeout); |
| 57 } | 56 } |
| 58 } | 57 } |
| 59 | 58 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 StackFrame* frame = frames_iterator.NextFrame(); | 146 StackFrame* frame = frames_iterator.NextFrame(); |
| 148 while (frame != NULL) { | 147 while (frame != NULL) { |
| 149 frame->VisitObjectPointers(visitor); | 148 frame->VisitObjectPointers(visitor); |
| 150 frame = frames_iterator.NextFrame(); | 149 frame = frames_iterator.NextFrame(); |
| 151 } | 150 } |
| 152 thread = thread->next_; | 151 thread = thread->next_; |
| 153 } | 152 } |
| 154 } | 153 } |
| 155 | 154 |
| 156 | 155 |
| 156 void ThreadRegistry::PrepareForGC() { |
| 157 MonitorLocker ml(monitor_); |
| 158 Thread* thread = active_list_; |
| 159 while (thread != NULL) { |
| 160 thread->PrepareForGC(); |
| 161 thread = thread->next_; |
| 162 } |
| 163 } |
| 164 |
| 165 |
| 157 void ThreadRegistry::AddThreadToActiveList(Thread* thread) { | 166 void ThreadRegistry::AddThreadToActiveList(Thread* thread) { |
| 158 ASSERT(thread != NULL); | 167 ASSERT(thread != NULL); |
| 159 ASSERT(monitor_->IsOwnedByCurrentThread()); | 168 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 160 thread->next_ = active_list_; | 169 thread->next_ = active_list_; |
| 161 active_list_ = thread; | 170 active_list_ = thread; |
| 162 } | 171 } |
| 163 | 172 |
| 164 | 173 |
| 165 void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) { | 174 void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) { |
| 166 ASSERT(thread != NULL); | 175 ASSERT(thread != NULL); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 217 |
| 209 | 218 |
| 210 void ThreadRegistry::CheckSafepointLocked() { | 219 void ThreadRegistry::CheckSafepointLocked() { |
| 211 int64_t last_round = -1; | 220 int64_t last_round = -1; |
| 212 while (in_rendezvous_) { | 221 while (in_rendezvous_) { |
| 213 ASSERT(round_ >= last_round); | 222 ASSERT(round_ >= last_round); |
| 214 if (round_ != last_round) { | 223 if (round_ != last_round) { |
| 215 ASSERT((last_round == -1) || (round_ == (last_round + 1))); | 224 ASSERT((last_round == -1) || (round_ == (last_round + 1))); |
| 216 last_round = round_; | 225 last_round = round_; |
| 217 // Participate in this round. | 226 // Participate in this round. |
| 218 // TODO(koda): Rename Thread::PrepareForGC and call it here? | |
| 219 if (--remaining_ == 0) { | 227 if (--remaining_ == 0) { |
| 220 // Ensure the organizing thread is notified. | 228 // Ensure the organizing thread is notified. |
| 221 // TODO(koda): Use separate condition variables and plain 'Notify'. | 229 // TODO(koda): Use separate condition variables and plain 'Notify'. |
| 222 monitor_->NotifyAll(); | 230 monitor_->NotifyAll(); |
| 223 } | 231 } |
| 224 } | 232 } |
| 225 monitor_->Wait(Monitor::kNoTimeout); | 233 monitor_->Wait(Monitor::kNoTimeout); |
| 226 // Note: Here, round_ is needed to detect and distinguish two cases: | 234 // Note: Here, round_ is needed to detect and distinguish two cases: |
| 227 // a) The old rendezvous is still in progress, so just keep waiting, or | 235 // a) The old rendezvous is still in progress, so just keep waiting, or |
| 228 // b) after ResumeAllThreads, another call to SafepointThreads was | 236 // b) after ResumeAllThreads, another call to SafepointThreads was |
| 229 // made before this thread got a chance to reaquire monitor_, thus this | 237 // made before this thread got a chance to reaquire monitor_, thus this |
| 230 // thread should (again) decrease remaining_ to indicate cooperation in | 238 // thread should (again) decrease remaining_ to indicate cooperation in |
| 231 // this new round. | 239 // this new round. |
| 232 } | 240 } |
| 233 } | 241 } |
| 234 | 242 |
| 235 | 243 |
| 236 intptr_t ThreadRegistry::CountScheduledLocked() { | 244 intptr_t ThreadRegistry::CountScheduledLocked() { |
| 237 intptr_t count = 0; | 245 intptr_t count = 0; |
| 238 Thread* current = active_list_; | 246 Thread* current = active_list_; |
| 239 while (current != NULL) { | 247 while (current != NULL) { |
| 240 ++count; | 248 ++count; |
| 241 current = current->next_; | 249 current = current->next_; |
| 242 } | 250 } |
| 243 return count; | 251 return count; |
| 244 } | 252 } |
| 245 | 253 |
| 246 } // namespace dart | 254 } // namespace dart |
| OLD | NEW |