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

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

Issue 1541073002: Implement safepointing of threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: self-review-comments Created 4 years, 11 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) 2016, 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/safepoint.h"
6
7 #include "vm/thread.h"
8 #include "vm/thread_registry.h"
9
10 namespace dart {
11
12 SafepointOperationScope::SafepointOperationScope(Thread* T) : StackResource(T) {
13 ASSERT(T != NULL);
14 Isolate* I = T->isolate();
15 ASSERT(I != NULL);
16
17 SafepointHandler* handler = I->safepoint_handler();
18 ASSERT(handler != NULL);
19
20 // Signal all threads to get to a safepoint and wait for them to
21 // get to a safepoint.
22 handler->SafepointThreads(T);
23 }
24
25
26 SafepointOperationScope::~SafepointOperationScope() {
27 Thread* T = thread();
28 ASSERT(T != NULL);
29 Isolate* I = T->isolate();
30 ASSERT(I != NULL);
31
32 // Resume all threads which are blocked for the safepoint operation.
33 SafepointHandler* handler = I->safepoint_handler();
34 ASSERT(handler != NULL);
35 handler->ResumeThreads(T);
36 }
37
38
39 SafepointHandler::SafepointHandler(Isolate* isolate)
40 : isolate_(isolate),
41 safepoint_lock_(new Monitor()),
42 number_threads_not_at_safepoint_(0),
43 safepoint_in_progress_(false) {
44 }
45
46
47 SafepointHandler::~SafepointHandler() {
48 ASSERT(safepoint_in_progress_ == false);
49 delete safepoint_lock_;
50 safepoint_lock_ = NULL;
51 isolate_ = NULL;
52 }
53
54
55 void SafepointHandler::SafepointThreads(Thread* T) {
56 {
57 // First grab the threads list lock for this isolate
58 // and check if a safepoint is already in progress. This
59 // ensures that two threads do not start a safepoint operation
60 // at the same time.
61 MonitorLocker sl(threads_lock());
62
63 // Now check to see if a safepoint operation is already in progress
64 // for this isolate, block if an operation is in progress.
65 while (safepoint_in_progress()) {
66 sl.WaitWithSafepointCheck(T);
67 }
68
69 // Set safepoint in progress by this thread.
70 set_safepoint_in_progress(true);
71
72 // Go over the active thread list and ensure that all threads active
73 // in the isolate reach a safepoint.
74 Thread* current = isolate()->thread_registry()->active_list();
75 while (current != NULL) {
76 MonitorLocker tl(current->thread_lock());
77 if (current != T) {
78 uint32_t state = current->SetSafepointRequested(true);
79 if (!Thread::IsAtSafepoint(state)) {
80 // Thread is not already at a safepoint so try to
81 // get it to a safepoint and wait for it to check in.
82 if (current->IsMutatorThread()) {
83 ASSERT(T->isolate() != NULL);
84 T->isolate()->ScheduleInterrupts(Isolate::kVMInterrupt);
85 }
86 MonitorLocker sl(safepoint_lock_);
87 ++number_threads_not_at_safepoint_;
88 }
89 } else {
90 current->SetAtSafepoint(true);
91 }
92 current = current->next();
93 }
94 }
95 // Now wait for all threads that are not already at a safepoint to check-in.
96 {
97 MonitorLocker sl(safepoint_lock_);
98 while (number_threads_not_at_safepoint_ > 0) {
99 sl.Wait();
100 }
101 }
102 }
103
104
105 void SafepointHandler::ResumeThreads(Thread* T) {
106 // First resume all the threads which are blocked for the safepoint
107 // operation.
108 MonitorLocker sl(threads_lock());
109 Thread* current = isolate()->thread_registry()->active_list();
110 while (current != NULL) {
111 MonitorLocker tl(current->thread_lock());
112 if (current != T) {
113 uint32_t state = current->SetSafepointRequested(false);
114 if (Thread::IsBlockedForSafepoint(state)) {
115 tl.Notify();
116 }
117 } else {
118 current->SetAtSafepoint(false);
119 }
120 current = current->next();
121 }
122 // Now set the safepoint_in_progress_ flag to false and notify all threads
123 // that are waiting to enter the isolate or waiting to start another
124 // safepoint operation.
125 set_safepoint_in_progress(false);
126 sl.NotifyAll();
127 }
128
129
130 void SafepointHandler::EnterSafepointUsingLock(Thread* T) {
131 MonitorLocker tl(T->thread_lock());
132 T->SetAtSafepoint(true);
133 if (T->IsSafepointRequested()) {
134 MonitorLocker sl(safepoint_lock_);
135 ASSERT(number_threads_not_at_safepoint_ > 0);
136 number_threads_not_at_safepoint_ -= 1;
137 sl.Notify();
138 }
139 }
140
141
142 void SafepointHandler::ExitSafepointUsingLock(Thread* T) {
143 MonitorLocker tl(T->thread_lock());
144 ASSERT(T->IsAtSafepoint());
145 while (T->IsSafepointRequested()) {
146 T->SetBlockedForSafepoint(true);
147 tl.Wait();
148 T->SetBlockedForSafepoint(false);
149 }
150 T->SetAtSafepoint(false);
151 }
152
153
154 void SafepointHandler::BlockForSafepoint(Thread* T) {
155 MonitorLocker tl(T->thread_lock());
156 if (T->IsSafepointRequested()) {
157 T->SetAtSafepoint(true);
158 {
159 MonitorLocker sl(safepoint_lock_);
160 ASSERT(number_threads_not_at_safepoint_ > 0);
161 number_threads_not_at_safepoint_ -= 1;
162 sl.Notify();
163 }
164 while (T->IsSafepointRequested()) {
165 T->SetBlockedForSafepoint(true);
166 tl.Wait();
167 T->SetBlockedForSafepoint(false);
168 }
169 T->SetAtSafepoint(false);
170 }
171 }
172
173 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698