OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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/safepoint.h" | 5 #include "vm/safepoint.h" |
6 | 6 |
7 #include "vm/thread.h" | 7 #include "vm/thread.h" |
8 #include "vm/thread_registry.h" | 8 #include "vm/thread_registry.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
11 | 11 |
12 SafepointOperationScope::SafepointOperationScope(Thread* T) : StackResource(T) { | 12 SafepointOperationScope::SafepointOperationScope(Thread* T) : StackResource(T) { |
13 ASSERT(T != NULL); | 13 ASSERT(T != NULL); |
14 Isolate* I = T->isolate(); | 14 Isolate* I = T->isolate(); |
15 ASSERT(I != NULL); | 15 ASSERT(I != NULL); |
16 ASSERT(T->no_safepoint_scope_depth() == 0); | 16 ASSERT(T->no_safepoint_scope_depth() == 0); |
17 | 17 |
18 SafepointHandler* handler = I->safepoint_handler(); | 18 SafepointHandler* handler = I->safepoint_handler(); |
19 ASSERT(handler != NULL); | 19 ASSERT(handler != NULL); |
20 | 20 |
21 // Signal all threads to get to a safepoint and wait for them to | 21 // Signal all threads to get to a safepoint and wait for them to |
22 // get to a safepoint. | 22 // get to a safepoint. |
23 handler->SafepointThreads(T); | 23 handler->SafepointThreads(T); |
24 } | 24 } |
25 | 25 |
26 | |
27 SafepointOperationScope::~SafepointOperationScope() { | 26 SafepointOperationScope::~SafepointOperationScope() { |
28 Thread* T = thread(); | 27 Thread* T = thread(); |
29 ASSERT(T != NULL); | 28 ASSERT(T != NULL); |
30 Isolate* I = T->isolate(); | 29 Isolate* I = T->isolate(); |
31 ASSERT(I != NULL); | 30 ASSERT(I != NULL); |
32 | 31 |
33 // Resume all threads which are blocked for the safepoint operation. | 32 // Resume all threads which are blocked for the safepoint operation. |
34 SafepointHandler* handler = I->safepoint_handler(); | 33 SafepointHandler* handler = I->safepoint_handler(); |
35 ASSERT(handler != NULL); | 34 ASSERT(handler != NULL); |
36 handler->ResumeThreads(T); | 35 handler->ResumeThreads(T); |
37 } | 36 } |
38 | 37 |
39 | |
40 SafepointHandler::SafepointHandler(Isolate* isolate) | 38 SafepointHandler::SafepointHandler(Isolate* isolate) |
41 : isolate_(isolate), | 39 : isolate_(isolate), |
42 safepoint_lock_(new Monitor()), | 40 safepoint_lock_(new Monitor()), |
43 number_threads_not_at_safepoint_(0), | 41 number_threads_not_at_safepoint_(0), |
44 safepoint_operation_count_(0), | 42 safepoint_operation_count_(0), |
45 owner_(NULL) {} | 43 owner_(NULL) {} |
46 | 44 |
47 | |
48 SafepointHandler::~SafepointHandler() { | 45 SafepointHandler::~SafepointHandler() { |
49 ASSERT(owner_ == NULL); | 46 ASSERT(owner_ == NULL); |
50 ASSERT(safepoint_operation_count_ == 0); | 47 ASSERT(safepoint_operation_count_ == 0); |
51 delete safepoint_lock_; | 48 delete safepoint_lock_; |
52 safepoint_lock_ = NULL; | 49 safepoint_lock_ = NULL; |
53 isolate_ = NULL; | 50 isolate_ = NULL; |
54 } | 51 } |
55 | 52 |
56 | |
57 void SafepointHandler::SafepointThreads(Thread* T) { | 53 void SafepointHandler::SafepointThreads(Thread* T) { |
58 { | 54 { |
59 // First grab the threads list lock for this isolate | 55 // First grab the threads list lock for this isolate |
60 // and check if a safepoint is already in progress. This | 56 // and check if a safepoint is already in progress. This |
61 // ensures that two threads do not start a safepoint operation | 57 // ensures that two threads do not start a safepoint operation |
62 // at the same time. | 58 // at the same time. |
63 MonitorLocker sl(threads_lock()); | 59 MonitorLocker sl(threads_lock()); |
64 | 60 |
65 // Now check to see if a safepoint operation is already in progress | 61 // Now check to see if a safepoint operation is already in progress |
66 // for this isolate, block if an operation is in progress. | 62 // for this isolate, block if an operation is in progress. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 // We have been waiting too long, start logging this as we might | 109 // We have been waiting too long, start logging this as we might |
114 // have an issue where a thread is not checking in for a safepoint. | 110 // have an issue where a thread is not checking in for a safepoint. |
115 OS::Print("Attempt:%" Pd " waiting for %d threads to check in\n", | 111 OS::Print("Attempt:%" Pd " waiting for %d threads to check in\n", |
116 num_attempts, number_threads_not_at_safepoint_); | 112 num_attempts, number_threads_not_at_safepoint_); |
117 } | 113 } |
118 } | 114 } |
119 } | 115 } |
120 } | 116 } |
121 } | 117 } |
122 | 118 |
123 | |
124 void SafepointHandler::ResumeThreads(Thread* T) { | 119 void SafepointHandler::ResumeThreads(Thread* T) { |
125 // First resume all the threads which are blocked for the safepoint | 120 // First resume all the threads which are blocked for the safepoint |
126 // operation. | 121 // operation. |
127 MonitorLocker sl(threads_lock()); | 122 MonitorLocker sl(threads_lock()); |
128 | 123 |
129 // First check if we are in a recursive safepoint operation, in that case | 124 // First check if we are in a recursive safepoint operation, in that case |
130 // we just decrement safepoint_operation_count and return. | 125 // we just decrement safepoint_operation_count and return. |
131 ASSERT(SafepointInProgress()); | 126 ASSERT(SafepointInProgress()); |
132 if (safepoint_operation_count() > 1) { | 127 if (safepoint_operation_count() > 1) { |
133 decrement_safepoint_operation_count(); | 128 decrement_safepoint_operation_count(); |
(...skipping 12 matching lines...) Expand all Loading... |
146 } | 141 } |
147 current = current->next(); | 142 current = current->next(); |
148 } | 143 } |
149 // Now reset the safepoint_in_progress_ state and notify all threads | 144 // Now reset the safepoint_in_progress_ state and notify all threads |
150 // that are waiting to enter the isolate or waiting to start another | 145 // that are waiting to enter the isolate or waiting to start another |
151 // safepoint operation. | 146 // safepoint operation. |
152 ResetSafepointInProgress(T); | 147 ResetSafepointInProgress(T); |
153 sl.NotifyAll(); | 148 sl.NotifyAll(); |
154 } | 149 } |
155 | 150 |
156 | |
157 void SafepointHandler::EnterSafepointUsingLock(Thread* T) { | 151 void SafepointHandler::EnterSafepointUsingLock(Thread* T) { |
158 MonitorLocker tl(T->thread_lock()); | 152 MonitorLocker tl(T->thread_lock()); |
159 T->SetAtSafepoint(true); | 153 T->SetAtSafepoint(true); |
160 if (T->IsSafepointRequested()) { | 154 if (T->IsSafepointRequested()) { |
161 MonitorLocker sl(safepoint_lock_); | 155 MonitorLocker sl(safepoint_lock_); |
162 ASSERT(number_threads_not_at_safepoint_ > 0); | 156 ASSERT(number_threads_not_at_safepoint_ > 0); |
163 number_threads_not_at_safepoint_ -= 1; | 157 number_threads_not_at_safepoint_ -= 1; |
164 sl.Notify(); | 158 sl.Notify(); |
165 } | 159 } |
166 } | 160 } |
167 | 161 |
168 | |
169 void SafepointHandler::ExitSafepointUsingLock(Thread* T) { | 162 void SafepointHandler::ExitSafepointUsingLock(Thread* T) { |
170 MonitorLocker tl(T->thread_lock()); | 163 MonitorLocker tl(T->thread_lock()); |
171 ASSERT(T->IsAtSafepoint()); | 164 ASSERT(T->IsAtSafepoint()); |
172 while (T->IsSafepointRequested()) { | 165 while (T->IsSafepointRequested()) { |
173 T->SetBlockedForSafepoint(true); | 166 T->SetBlockedForSafepoint(true); |
174 tl.Wait(); | 167 tl.Wait(); |
175 T->SetBlockedForSafepoint(false); | 168 T->SetBlockedForSafepoint(false); |
176 } | 169 } |
177 T->SetAtSafepoint(false); | 170 T->SetAtSafepoint(false); |
178 } | 171 } |
179 | 172 |
180 | |
181 void SafepointHandler::BlockForSafepoint(Thread* T) { | 173 void SafepointHandler::BlockForSafepoint(Thread* T) { |
182 MonitorLocker tl(T->thread_lock()); | 174 MonitorLocker tl(T->thread_lock()); |
183 if (T->IsSafepointRequested()) { | 175 if (T->IsSafepointRequested()) { |
184 T->SetAtSafepoint(true); | 176 T->SetAtSafepoint(true); |
185 { | 177 { |
186 MonitorLocker sl(safepoint_lock_); | 178 MonitorLocker sl(safepoint_lock_); |
187 ASSERT(number_threads_not_at_safepoint_ > 0); | 179 ASSERT(number_threads_not_at_safepoint_ > 0); |
188 number_threads_not_at_safepoint_ -= 1; | 180 number_threads_not_at_safepoint_ -= 1; |
189 sl.Notify(); | 181 sl.Notify(); |
190 } | 182 } |
191 while (T->IsSafepointRequested()) { | 183 while (T->IsSafepointRequested()) { |
192 T->SetBlockedForSafepoint(true); | 184 T->SetBlockedForSafepoint(true); |
193 tl.Wait(); | 185 tl.Wait(); |
194 T->SetBlockedForSafepoint(false); | 186 T->SetBlockedForSafepoint(false); |
195 } | 187 } |
196 T->SetAtSafepoint(false); | 188 T->SetAtSafepoint(false); |
197 } | 189 } |
198 } | 190 } |
199 | 191 |
200 } // namespace dart | 192 } // namespace dart |
OLD | NEW |