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/safepoint.cc

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

Powered by Google App Engine
This is Rietveld 408576698