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

Side by Side Diff: runtime/vm/thread_registry.cc

Issue 1533023002: - Make sure to prepare all threads for GC. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address review comments. Created 5 years 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/thread_registry.h ('k') | runtime/vm/thread_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« 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