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

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

Issue 1259223005: Safepoint interface and unit tests. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Ready for review. Created 5 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/thread_registry.h"
6
7 #include "vm/isolate.h"
8 #include "vm/lockers.h"
9
10 namespace dart {
11
12 void ThreadRegistry::SafepointAllThreads() {
13 MonitorLocker ml(monitor_);
14 // First wait for any older rounds that are still in progress.
15 while (in_rendezvous_) {
16 CheckSafepointLocked();
17 }
18 // Start a new round.
19 in_rendezvous_ = true;
20 ++round_;
21 remaining_ = CountScheduledLocked();
22 Isolate* isolate = Isolate::Current();
23 // We only expect this method to be called from within the isolate itself.
24 ASSERT(isolate->thread_registry() == this);
25 // TODO(koda): Rename Thread::PrepareForGC and call it here?
26 --remaining_; // Exclude this thread from the count.
27 // Ensure the main mutator will reach a safepoint (could be running Dart).
28 if (Thread::Current() != isolate->mutator_thread()) {
29 isolate->ScheduleInterrupts(Isolate::kSafepointInterrrupt);
Ivan Posva 2015/07/31 20:28:09 Talk like a pirate constants?
koda 2015/07/31 22:40:44 Rrrenamed to kVMInterrupt.
30 }
31 while (remaining_ > 0) {
32 ml.Wait(Monitor::kNoTimeout);
33 }
34 }
35
36
37 void ThreadRegistry::ResumeAllThreads() {
38 MonitorLocker ml(monitor_);
39 ASSERT(in_rendezvous_);
40 in_rendezvous_ = false;
41 ml.NotifyAll();
42 }
43
44
45 void ThreadRegistry::CheckSafepointLocked() {
46 int64_t last_round = -1;
47 while (in_rendezvous_) {
48 ASSERT(round_ >= last_round);
49 if (round_ > last_round) {
50 ASSERT((last_round == -1) || (round_ == (last_round + 1)));
51 last_round = round_;
52 // Participate in this round.
53 // TODO(koda): Rename Thread::PrepareForGC and call it here?
54 if (--remaining_ == 0) {
55 // Ensure the organizing thread is notified.
56 // TODO(koda): Use separate condition variables and plain 'Notify'.
57 monitor_->NotifyAll();
Ivan Posva 2015/07/31 20:28:09 Having to use NotifyAll generally points at some p
koda 2015/07/31 22:40:44 I agree that it is inelegant that they all wake up
58 }
59 }
60 monitor_->Wait(Monitor::kNoTimeout);
61 // Note: Here, round_ is needed to detect and distinguish two cases:
62 // a) The old rendezvous is still in progress, so just keep waiting, or
63 // b) after ResumeAllThreads, another call to SafepointAllThreads was
64 // made before this thread got a chance to reaquire monitor_, thus this
65 // thread should (again) decrease remaining_ to indicate cooperation in
66 // this new round.
67 }
68 }
69
70
71 intptr_t ThreadRegistry::CountScheduledLocked() {
72 intptr_t count = 0;
73 for (int i = 0; i < entries_.length(); ++i) {
74 const Entry& entry = entries_[i];
75 if (entry.scheduled) {
76 ++count;
77 }
78 }
79 return count;
80 }
81
82 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698