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

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

Issue 1541073002: Implement safepointing of threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix-typo Created 4 years, 10 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
« no previous file with comments | « runtime/vm/runtime_entry.h ('k') | runtime/vm/safepoint.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef VM_SAFEPOINT_H_
6 #define VM_SAFEPOINT_H_
7
8 #include "vm/globals.h"
9 #include "vm/lockers.h"
10 #include "vm/thread.h"
11
12 namespace dart {
13
14 // A stack based scope that can be used to perform an operation after getting
15 // all threads to a safepoint. At the end of the operation all the threads are
16 // resumed.
17 class SafepointOperationScope : public StackResource {
18 public:
19 explicit SafepointOperationScope(Thread* T);
20 ~SafepointOperationScope();
21
22 private:
23 DISALLOW_COPY_AND_ASSIGN(SafepointOperationScope);
24 };
25
26
27 // Implements handling of safepoint operations for all threads in an Isolate.
28 class SafepointHandler {
29 public:
30 explicit SafepointHandler(Isolate* I);
31 ~SafepointHandler();
32
33 void EnterSafepointUsingLock(Thread* T);
34 void ExitSafepointUsingLock(Thread* T);
35
36 void SafepointThreads(Thread* T);
37 void ResumeThreads(Thread* T);
38
39 void BlockForSafepoint(Thread* T);
40
41 private:
42 Isolate* isolate() const { return isolate_; }
43 Monitor* threads_lock() const { return isolate_->threads_lock(); }
44 bool safepoint_in_progress() const {
45 ASSERT(threads_lock()->IsOwnedByCurrentThread());
46 return safepoint_in_progress_;
47 }
48 void set_safepoint_in_progress(bool value) {
49 ASSERT(threads_lock()->IsOwnedByCurrentThread());
50 safepoint_in_progress_ = value;
51 }
52
53 Isolate* isolate_;
54
55 // Monitor used by thread initiating a safepoint operation to track threads
56 // not at a safepoint and wait for these threads to reach a safepoint.
57 Monitor* safepoint_lock_;
58 int32_t number_threads_not_at_safepoint_;
59
60 // Flag to indicate if a safepoint operation is currently in progress.
61 bool safepoint_in_progress_;
62
63 friend class Isolate;
64 friend class SafepointOperationScope;
65 };
66
67
68 /*
69 * Set of StackResource classes to track thread execution state transitions:
70 *
71 * kThreadInGenerated transitioning to
72 * ==> kThreadInVM:
73 * - set_execution_state(kThreadInVM).
74 * - block if safepoint is requested.
75 * ==> kThreadInNative:
76 * - set_execution_state(kThreadInNative).
77 * - EnterSafepoint().
78 * ==> kThreadInBlockedState:
79 * - Invalid transition
80 *
81 * kThreadInVM transitioning to
82 * ==> kThreadInGenerated
83 * - set_execution_state(kThreadInGenerated).
84 * ==> kThreadInNative
85 * - set_execution_state(kThreadInNative).
86 * - EnterSafepoint.
87 * ==> kThreadInBlockedState
88 * - set_execution_state(kThreadInBlockedState).
89 * - EnterSafepoint.
90 *
91 * kThreadInNative transitioning to
92 * ==> kThreadInGenerated
93 * - ExitSafepoint.
94 * - set_execution_state(kThreadInGenerated).
95 * ==> kThreadInVM
96 * - ExitSafepoint.
97 * - set_execution_state(kThreadInVM).
98 * ==> kThreadInBlocked
99 * - Invalid transition.
100 *
101 * kThreadInBlocked transitioning to
102 * ==> kThreadInVM
103 * - ExitSafepoint.
104 * - set_execution_state(kThreadInVM).
105 * ==> kThreadInNative
106 * - Invalid transition.
107 * ==> kThreadInGenerated
108 * - Invalid transition.
109 */
110 class TransitionSafepointState : public StackResource {
111 public:
112 explicit TransitionSafepointState(Thread* T) : StackResource(T) {}
113 ~TransitionSafepointState() {}
114
115 SafepointHandler* handler() const {
116 ASSERT(thread()->isolate() != NULL);
117 ASSERT(thread()->isolate()->safepoint_handler() != NULL);
118 return thread()->isolate()->safepoint_handler();
119 }
120
121 private:
122 DISALLOW_COPY_AND_ASSIGN(TransitionSafepointState);
123 };
124
125
126 // TransitionGeneratedToVM is used to transition the safepoint state of a
127 // thread from "running generated code" to "running vm code" and ensures
128 // that the state is reverted back to "running generated code" when
129 // exiting the scope/frame.
130 class TransitionGeneratedToVM : public TransitionSafepointState {
131 public:
132 explicit TransitionGeneratedToVM(Thread* T) : TransitionSafepointState(T) {
133 ASSERT(T == Thread::Current());
134 ASSERT(T->execution_state() == Thread::kThreadInGenerated);
135 T->set_execution_state(Thread::kThreadInVM);
136 // Fast check to see if a safepoint is requested or not.
137 // We do the more expensive operation of blocking the thread
138 // only if a safepoint is requested.
139 if (T->IsSafepointRequested()) {
140 handler()->BlockForSafepoint(T);
141 }
142 }
143
144 ~TransitionGeneratedToVM() {
145 ASSERT(thread()->execution_state() == Thread::kThreadInVM);
146 thread()->set_execution_state(Thread::kThreadInGenerated);
147 }
148
149 private:
150 DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToVM);
151 };
152
153
154 // TransitionGeneratedToNative is used to transition the safepoint state of a
155 // thread from "running generated code" to "running native code" and ensures
156 // that the state is reverted back to "running generated code" when
157 // exiting the scope/frame.
158 class TransitionGeneratedToNative : public TransitionSafepointState {
159 public:
160 explicit TransitionGeneratedToNative(Thread* T)
161 : TransitionSafepointState(T) {
162 // Native code is considered to be at a safepoint and so we mark it
163 // accordingly.
164 ASSERT(T->execution_state() == Thread::kThreadInGenerated);
165 T->set_execution_state(Thread::kThreadInNative);
166 T->EnterSafepoint();
167 }
168
169 ~TransitionGeneratedToNative() {
170 // We are returning to generated code and so we are not at a safepoint
171 // anymore.
172 ASSERT(thread()->execution_state() == Thread::kThreadInNative);
173 thread()->ExitSafepoint();
174 thread()->set_execution_state(Thread::kThreadInGenerated);
175 }
176
177 private:
178 DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToNative);
179 };
180
181
182 // TransitionVMToBlocked is used to transition the safepoint state of a
183 // thread from "running vm code" to "blocked on a monitor" and ensures
184 // that the state is reverted back to "running vm code" when
185 // exiting the scope/frame.
186 class TransitionVMToBlocked : public TransitionSafepointState {
187 public:
188 explicit TransitionVMToBlocked(Thread* T) : TransitionSafepointState(T) {
189 // A thread blocked on a monitor is considered to be at a safepoint.
190 ASSERT(T->execution_state() == Thread::kThreadInVM);
191 T->set_execution_state(Thread::kThreadInBlockedState);
192 T->EnterSafepoint();
193 }
194
195 ~TransitionVMToBlocked() {
196 // We are returning to vm code and so we are not at a safepoint anymore.
197 ASSERT(thread()->execution_state() == Thread::kThreadInBlockedState);
198 thread()->ExitSafepoint();
199 thread()->set_execution_state(Thread::kThreadInVM);
200 }
201
202 private:
203 DISALLOW_COPY_AND_ASSIGN(TransitionVMToBlocked);
204 };
205
206
207 // TransitionVMToNative is used to transition the safepoint state of a
208 // thread from "running vm code" to "running native code" and ensures
209 // that the state is reverted back to "running vm code" when
210 // exiting the scope/frame.
211 class TransitionVMToNative : public TransitionSafepointState {
212 public:
213 explicit TransitionVMToNative(Thread* T) : TransitionSafepointState(T) {
214 // A thread running native code is considered to be at a safepoint.
215 ASSERT(T->execution_state() == Thread::kThreadInVM);
216 T->set_execution_state(Thread::kThreadInNative);
217 T->EnterSafepoint();
218 }
219
220 ~TransitionVMToNative() {
221 // We are returning to vm code and so we are not at a safepoint anymore.
222 ASSERT(thread()->execution_state() == Thread::kThreadInNative);
223 thread()->ExitSafepoint();
224 thread()->set_execution_state(Thread::kThreadInVM);
225 }
226
227 private:
228 DISALLOW_COPY_AND_ASSIGN(TransitionVMToNative);
229 };
230
231
232 // TransitionVMToGenerated is used to transition the safepoint state of a
233 // thread from "running vm code" to "running generated code" and ensures
234 // that the state is reverted back to "running vm code" when
235 // exiting the scope/frame.
236 class TransitionVMToGenerated : public TransitionSafepointState {
237 public:
238 explicit TransitionVMToGenerated(Thread* T) : TransitionSafepointState(T) {
239 ASSERT(T == Thread::Current());
240 ASSERT(T->execution_state() == Thread::kThreadInVM);
241 T->set_execution_state(Thread::kThreadInGenerated);
242 }
243
244 ~TransitionVMToGenerated() {
245 ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
246 thread()->set_execution_state(Thread::kThreadInVM);
247 // Fast check to see if a safepoint is requested or not.
248 // We do the more expensive operation of blocking the thread
249 // only if a safepoint is requested.
250 if (thread()->IsSafepointRequested()) {
251 handler()->BlockForSafepoint(thread());
252 }
253 }
254
255 private:
256 DISALLOW_COPY_AND_ASSIGN(TransitionVMToGenerated);
257 };
258
259
260 // TransitionNativeToVM is used to transition the safepoint state of a
261 // thread from "running native code" to "running vm code" and ensures
262 // that the state is reverted back to "running native code" when
263 // exiting the scope/frame.
264 class TransitionNativeToVM : public TransitionSafepointState {
265 public:
266 explicit TransitionNativeToVM(Thread* T) : TransitionSafepointState(T) {
267 // We are about to execute vm code and so we are not at a safepoint anymore.
268 ASSERT(T->execution_state() == Thread::kThreadInNative);
269 T->ExitSafepoint();
270 T->set_execution_state(Thread::kThreadInVM);
271 }
272
273 ~TransitionNativeToVM() {
274 // We are returning to native code and so we are at a safepoint.
275 ASSERT(thread()->execution_state() == Thread::kThreadInVM);
276 thread()->set_execution_state(Thread::kThreadInNative);
277 thread()->EnterSafepoint();
278 }
279
280 private:
281 DISALLOW_COPY_AND_ASSIGN(TransitionNativeToVM);
282 };
283
284
285 // TransitionToGenerated is used to transition the safepoint state of a
286 // thread from "running vm code" or "running native code" to
287 // "running generated code" and ensures that the state is reverted back
288 // to "running vm code" or "running native code" when exiting the
289 // scope/frame.
290 class TransitionToGenerated : public TransitionSafepointState {
291 public:
292 explicit TransitionToGenerated(Thread* T)
293 : TransitionSafepointState(T),
294 execution_state_(T->execution_state()) {
295 ASSERT(T == Thread::Current());
296 ASSERT((execution_state_ == Thread::kThreadInVM) ||
297 (execution_state_ == Thread::kThreadInNative));
298 if (execution_state_ == Thread::kThreadInNative) {
299 T->ExitSafepoint();
300 }
301 T->set_execution_state(Thread::kThreadInGenerated);
302 }
303
304 ~TransitionToGenerated() {
305 ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
306 if (execution_state_ == Thread::kThreadInNative) {
307 thread()->set_execution_state(Thread::kThreadInNative);
308 thread()->EnterSafepoint();
309 } else {
310 ASSERT(execution_state_ == Thread::kThreadInVM);
311 thread()->set_execution_state(Thread::kThreadInVM);
312 // Fast check to see if a safepoint is requested or not.
313 // We do the more expensive operation of blocking the thread
314 // only if a safepoint is requested.
315 if (thread()->IsSafepointRequested()) {
316 handler()->BlockForSafepoint(thread());
317 }
318 }
319 }
320
321 private:
322 int16_t execution_state_;
323 DISALLOW_COPY_AND_ASSIGN(TransitionToGenerated);
324 };
325
326 } // namespace dart
327
328 #endif // VM_SAFEPOINT_H_
OLDNEW
« no previous file with comments | « runtime/vm/runtime_entry.h ('k') | runtime/vm/safepoint.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698