11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "logging/log.hpp"
27 #include "logging/logStream.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "runtime/handshake.hpp"
30 #include "runtime/interfaceSupport.inline.hpp"
31 #include "runtime/osThread.hpp"
32 #include "runtime/semaphore.inline.hpp"
33 #include "runtime/task.hpp"
34 #include "runtime/timerTrace.hpp"
35 #include "runtime/thread.hpp"
36 #include "runtime/vmThread.hpp"
37 #include "utilities/formatBuffer.hpp"
38 #include "utilities/preserveException.hpp"
39
40 class HandshakeOperation: public StackObj {
41 public:
42 virtual void do_handshake(JavaThread* thread) = 0;
43 virtual void cancel_handshake(JavaThread* thread) = 0;
44 };
45
46 class HandshakeThreadsOperation: public HandshakeOperation {
47 Semaphore _done;
48 ThreadClosure* _thread_cl;
49
50 public:
51 HandshakeThreadsOperation(ThreadClosure* cl) : _done(0), _thread_cl(cl) {}
52 void do_handshake(JavaThread* thread);
53 void cancel_handshake(JavaThread* thread) { _done.signal(); };
54
55 bool thread_has_completed() { return _done.trywait(); }
56 };
57
58 class VM_Handshake: public VM_Operation {
59 HandshakeThreadsOperation* const _op;
60 const jlong _handshake_timeout;
61 public:
62 bool evaluate_at_safepoint() const { return false; }
63
64 bool evaluate_concurrently() const { return false; }
65
66 protected:
67
68 VM_Handshake(HandshakeThreadsOperation* op) :
69 _op(op),
70 _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)) {}
71
72 void set_handshake(JavaThread* target) {
73 target->set_handshake_operation(_op);
74 }
75
76 // This method returns true for threads completed their operation
77 // and true for threads canceled their operation.
78 // A cancellation can happen if the thread is exiting.
79 bool poll_for_completed_thread() { return _op->thread_has_completed(); }
80
81 bool handshake_has_timed_out(jlong start_time);
82 static void handle_timeout();
83 };
84
85 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
86 // Check if handshake operation has timed out
87 if (_handshake_timeout > 0) {
88 return os::elapsed_counter() >= (start_time + _handshake_timeout);
89 }
90 return false;
91 }
92
93 void VM_Handshake::handle_timeout() {
94 LogStreamHandle(Warning, handshake) log_stream;
95 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
96 if (thr->has_handshake()) {
97 log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
98 thr->print_thread_state_on(&log_stream);
99 }
100 }
101 log_stream.flush();
102 fatal("Handshake operation timed out");
103 }
104
105
106 class VM_HandshakeOneThread: public VM_Handshake {
107 JavaThread* _target;
108 bool _thread_alive;
109 public:
110 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
111 VM_Handshake(op), _target(target), _thread_alive(false) {}
112
113 void doit() {
114 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
115
116 {
117 ThreadsListHandle tlh;
118 if (tlh.includes(_target)) {
119 set_handshake(_target);
120 _thread_alive = true;
121 }
122 }
123
124 if (!_thread_alive) {
125 return;
126 }
127
128 if (!UseMembar) {
129 os::serialize_thread_states();
130 }
131
132 log_trace(handshake)("Thread signaled, begin processing by VMThtread");
133 jlong start_time = os::elapsed_counter();
138
139 // We need to re-think this with SMR ThreadsList.
140 // There is an assumption in the code that the Threads_lock should be
141 // locked during certain phases.
142 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
143 ThreadsListHandle tlh;
144 if (tlh.includes(_target)) {
145 // Warning _target's address might be re-used.
146 // handshake_process_by_vmthread will check the semaphore for us again.
147 // Since we can't have more then one handshake in flight a reuse of
148 // _target's address should be okay since the new thread will not have
149 // an operation.
150 _target->handshake_process_by_vmthread();
151 } else {
152 // We can't warn here since the thread does cancel_handshake after
153 // it has been removed from the ThreadsList. So we should just keep
154 // looping here until while below returns false. If we have a bug,
155 // then we hang here, which is good for debugging.
156 }
157 } while (!poll_for_completed_thread());
158 }
159
160 VMOp_Type type() const { return VMOp_HandshakeOneThread; }
161
162 bool thread_alive() const { return _thread_alive; }
163 };
164
165 class VM_HandshakeAllThreads: public VM_Handshake {
166 public:
167 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
168
169 void doit() {
170 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
171
172 int number_of_threads_issued = 0;
173 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
174 set_handshake(thr);
175 number_of_threads_issued++;
176 }
177
178 if (number_of_threads_issued < 1) {
179 log_debug(handshake)("No threads to handshake.");
180 return;
181 }
182
183 if (!UseMembar) {
184 os::serialize_thread_states();
185 }
186
187 log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
188 const jlong start_time = os::elapsed_counter();
189 int number_of_threads_completed = 0;
196 // Have VM thread perform the handshake operation for blocked threads.
197 // Observing a blocked state may of course be transient but the processing is guarded
198 // by semaphores and we optimistically begin by working on the blocked threads
199 {
200 // We need to re-think this with SMR ThreadsList.
201 // There is an assumption in the code that the Threads_lock should
202 // be locked during certain phases.
203 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
204 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
205 // A new thread on the ThreadsList will not have an operation,
206 // hence it is skipped in handshake_process_by_vmthread.
207 thr->handshake_process_by_vmthread();
208 }
209 }
210
211 while (poll_for_completed_thread()) {
212 // Includes canceled operations by exiting threads.
213 number_of_threads_completed++;
214 }
215
216 } while (number_of_threads_issued != number_of_threads_completed);
217 }
218
219 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
220 };
221
222 class VM_HandshakeFallbackOperation : public VM_Operation {
223 ThreadClosure* _thread_cl;
224 Thread* _target_thread;
225 bool _all_threads;
226 bool _thread_alive;
227 public:
228 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
229 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
230 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
231 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
232
233 void doit() {
234 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
235 if (_all_threads || t == _target_thread) {
236 if (t == _target_thread) {
237 _thread_alive = true;
238 }
239 _thread_cl->do_thread(t);
240 }
241 }
242 }
243
244 VMOp_Type type() const { return VMOp_HandshakeFallback; }
245 bool thread_alive() const { return _thread_alive; }
246 };
247
248 #undef ALL_JAVA_THREADS
249
250 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
251 ResourceMark rm;
252 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
253 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
254 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
255 _thread_cl->do_thread(thread);
256
257 // Use the semaphore to inform the VM thread that we have completed the operation
258 _done.signal();
259 }
260
261 void Handshake::execute(ThreadClosure* thread_cl) {
262 if (ThreadLocalHandshakes) {
263 HandshakeThreadsOperation cto(thread_cl);
264 VM_HandshakeAllThreads handshake(&cto);
265 VMThread::execute(&handshake);
266 } else {
267 VM_HandshakeFallbackOperation op(thread_cl);
268 VMThread::execute(&op);
269 }
270 }
271
272 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
273 if (ThreadLocalHandshakes) {
274 HandshakeThreadsOperation cto(thread_cl);
275 VM_HandshakeOneThread handshake(&cto, target);
276 VMThread::execute(&handshake);
277 return handshake.thread_alive();
278 } else {
279 VM_HandshakeFallbackOperation op(thread_cl, target);
280 VMThread::execute(&op);
281 return op.thread_alive();
282 }
283 }
284
285 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _vmthread_holds_semaphore(false), _thread_in_process_handshake(false) {}
286
287 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
288 _operation = op;
289 SafepointMechanism::arm_local_poll(target);
290 }
291
292 void HandshakeState::clear_handshake(JavaThread* target) {
293 _operation = NULL;
294 SafepointMechanism::disarm_local_poll(target);
295 }
296
297 void HandshakeState::process_self_inner(JavaThread* thread) {
298 assert(Thread::current() == thread, "should call from thread");
299 CautiouslyPreserveExceptionMark pem(thread);
300 ThreadInVMForHandshake tivm(thread);
301 if (!_semaphore.trywait()) {
302 _semaphore.wait_with_safepoint_check(thread);
303 }
304 if (has_operation()) {
305 HandshakeOperation* op = _operation;
306 clear_handshake(thread);
307 if (op != NULL) {
308 op->do_handshake(thread);
309 }
310 }
311 _semaphore.signal();
312 }
313
314 void HandshakeState::cancel_inner(JavaThread* thread) {
315 assert(Thread::current() == thread, "should call from thread");
316 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
317 #ifdef DEBUG
318 {
319 ThreadsListHandle tlh;
320 assert(!tlh.includes(_target), "java thread must not be on threads list");
321 }
322 #endif
323 HandshakeOperation* op = _operation;
324 clear_handshake(thread);
325 if (op != NULL) {
326 op->cancel_handshake(thread);
327 }
328 }
329
330 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
331 return SafepointSynchronize::safepoint_safe(target, target->thread_state());
332 }
333
334 bool HandshakeState::claim_handshake_for_vmthread() {
335 if (_semaphore.trywait()) {
336 if (has_operation()) {
337 _vmthread_holds_semaphore = true;
338 } else {
339 _semaphore.signal();
340 }
341 }
342 return _vmthread_holds_semaphore;
343 }
344
345 void HandshakeState::process_by_vmthread(JavaThread* target) {
346 assert(Thread::current()->is_VM_thread(), "should call from vm thread");
347
348 if (!has_operation()) {
349 // JT has already cleared its handshake
350 return;
351 }
352
353 if (!vmthread_can_process_handshake(target)) {
354 // JT is observed in an unsafe state, it must notice the handshake itself
355 return;
356 }
357
358 // If we own the semaphore at this point and while owning the semaphore
359 // can observe a safe state the thread cannot possibly continue without
360 // getting caught by the semaphore.
361 if (claim_handshake_for_vmthread() && vmthread_can_process_handshake(target)) {
362 guarantee(!_semaphore.trywait(), "we should already own the semaphore");
363
364 _operation->do_handshake(target);
365 clear_handshake(target);
366 _vmthread_holds_semaphore = false;
367 // Release the thread
368 _semaphore.signal();
369 }
370 }
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "logging/log.hpp"
27 #include "logging/logStream.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "runtime/handshake.hpp"
30 #include "runtime/interfaceSupport.inline.hpp"
31 #include "runtime/orderAccess.hpp"
32 #include "runtime/osThread.hpp"
33 #include "runtime/semaphore.inline.hpp"
34 #include "runtime/task.hpp"
35 #include "runtime/timerTrace.hpp"
36 #include "runtime/thread.hpp"
37 #include "runtime/vmThread.hpp"
38 #include "utilities/formatBuffer.hpp"
39 #include "utilities/preserveException.hpp"
40
41 class HandshakeOperation: public StackObj {
42 public:
43 virtual void do_handshake(JavaThread* thread) = 0;
44 virtual void cancel_handshake(JavaThread* thread) = 0;
45 };
46
47 class HandshakeThreadsOperation: public HandshakeOperation {
48 static Semaphore _done;
49 ThreadClosure* _thread_cl;
50
51 public:
52 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
53 void do_handshake(JavaThread* thread);
54 void cancel_handshake(JavaThread* thread) { _done.signal(); };
55
56 bool thread_has_completed() { return _done.trywait(); }
57
58 #ifdef ASSERT
59 void check_state() {
60 assert(!_done.trywait(), "Must be zero");
61 }
62 #endif
63 };
64
65 Semaphore HandshakeThreadsOperation::_done(0);
66
67 class VM_Handshake: public VM_Operation {
68 const jlong _handshake_timeout;
69 public:
70 bool evaluate_at_safepoint() const { return false; }
71
72 bool evaluate_concurrently() const { return false; }
73
74 protected:
75 HandshakeThreadsOperation* const _op;
76
77 VM_Handshake(HandshakeThreadsOperation* op) :
78 _op(op),
79 _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)) {}
80
81 void set_handshake(JavaThread* target) {
82 target->set_handshake_operation(_op);
83 }
84
85 // This method returns true for threads completed their operation
86 // and true for threads canceled their operation.
87 // A cancellation can happen if the thread is exiting.
88 bool poll_for_completed_thread() { return _op->thread_has_completed(); }
89
90 bool handshake_has_timed_out(jlong start_time);
91 static void handle_timeout();
92 };
93
94 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
95 // Check if handshake operation has timed out
96 if (_handshake_timeout > 0) {
97 return os::elapsed_counter() >= (start_time + _handshake_timeout);
98 }
99 return false;
100 }
101
102 void VM_Handshake::handle_timeout() {
103 LogStreamHandle(Warning, handshake) log_stream;
104 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
105 if (thr->has_handshake()) {
106 log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
107 thr->print_thread_state_on(&log_stream);
108 }
109 }
110 log_stream.flush();
111 fatal("Handshake operation timed out");
112 }
113
114 class VM_HandshakeOneThread: public VM_Handshake {
115 JavaThread* _target;
116 bool _thread_alive;
117 public:
118 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
119 VM_Handshake(op), _target(target), _thread_alive(false) {}
120
121 void doit() {
122 DEBUG_ONLY(_op->check_state();)
123 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
124
125 {
126 ThreadsListHandle tlh;
127 if (tlh.includes(_target)) {
128 set_handshake(_target);
129 _thread_alive = true;
130 }
131 }
132
133 if (!_thread_alive) {
134 return;
135 }
136
137 if (!UseMembar) {
138 os::serialize_thread_states();
139 }
140
141 log_trace(handshake)("Thread signaled, begin processing by VMThtread");
142 jlong start_time = os::elapsed_counter();
147
148 // We need to re-think this with SMR ThreadsList.
149 // There is an assumption in the code that the Threads_lock should be
150 // locked during certain phases.
151 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
152 ThreadsListHandle tlh;
153 if (tlh.includes(_target)) {
154 // Warning _target's address might be re-used.
155 // handshake_process_by_vmthread will check the semaphore for us again.
156 // Since we can't have more then one handshake in flight a reuse of
157 // _target's address should be okay since the new thread will not have
158 // an operation.
159 _target->handshake_process_by_vmthread();
160 } else {
161 // We can't warn here since the thread does cancel_handshake after
162 // it has been removed from the ThreadsList. So we should just keep
163 // looping here until while below returns false. If we have a bug,
164 // then we hang here, which is good for debugging.
165 }
166 } while (!poll_for_completed_thread());
167 DEBUG_ONLY(_op->check_state();)
168 }
169
170 VMOp_Type type() const { return VMOp_HandshakeOneThread; }
171
172 bool thread_alive() const { return _thread_alive; }
173 };
174
175 class VM_HandshakeAllThreads: public VM_Handshake {
176 public:
177 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
178
179 void doit() {
180 DEBUG_ONLY(_op->check_state();)
181 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
182
183 int number_of_threads_issued = 0;
184 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
185 set_handshake(thr);
186 number_of_threads_issued++;
187 }
188
189 if (number_of_threads_issued < 1) {
190 log_debug(handshake)("No threads to handshake.");
191 return;
192 }
193
194 if (!UseMembar) {
195 os::serialize_thread_states();
196 }
197
198 log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
199 const jlong start_time = os::elapsed_counter();
200 int number_of_threads_completed = 0;
207 // Have VM thread perform the handshake operation for blocked threads.
208 // Observing a blocked state may of course be transient but the processing is guarded
209 // by semaphores and we optimistically begin by working on the blocked threads
210 {
211 // We need to re-think this with SMR ThreadsList.
212 // There is an assumption in the code that the Threads_lock should
213 // be locked during certain phases.
214 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
215 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
216 // A new thread on the ThreadsList will not have an operation,
217 // hence it is skipped in handshake_process_by_vmthread.
218 thr->handshake_process_by_vmthread();
219 }
220 }
221
222 while (poll_for_completed_thread()) {
223 // Includes canceled operations by exiting threads.
224 number_of_threads_completed++;
225 }
226
227 } while (number_of_threads_issued > number_of_threads_completed);
228 assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
229 DEBUG_ONLY(_op->check_state();)
230 }
231
232 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
233 };
234
235 class VM_HandshakeFallbackOperation : public VM_Operation {
236 ThreadClosure* _thread_cl;
237 Thread* _target_thread;
238 bool _all_threads;
239 bool _thread_alive;
240 public:
241 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
242 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
243 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
244 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
245
246 void doit() {
247 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
248 if (_all_threads || t == _target_thread) {
249 if (t == _target_thread) {
250 _thread_alive = true;
251 }
252 _thread_cl->do_thread(t);
253 }
254 }
255 }
256
257 VMOp_Type type() const { return VMOp_HandshakeFallback; }
258 bool thread_alive() const { return _thread_alive; }
259 };
260
261 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
262 ResourceMark rm;
263 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
264 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
265 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
266 _thread_cl->do_thread(thread);
267
268 // Use the semaphore to inform the VM thread that we have completed the operation
269 _done.signal();
270 }
271
272 void Handshake::execute(ThreadClosure* thread_cl) {
273 if (ThreadLocalHandshakes) {
274 HandshakeThreadsOperation cto(thread_cl);
275 VM_HandshakeAllThreads handshake(&cto);
276 VMThread::execute(&handshake);
277 } else {
278 VM_HandshakeFallbackOperation op(thread_cl);
279 VMThread::execute(&op);
280 }
281 }
282
283 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
284 if (ThreadLocalHandshakes) {
285 HandshakeThreadsOperation cto(thread_cl);
286 VM_HandshakeOneThread handshake(&cto, target);
287 VMThread::execute(&handshake);
288 return handshake.thread_alive();
289 } else {
290 VM_HandshakeFallbackOperation op(thread_cl, target);
291 VMThread::execute(&op);
292 return op.thread_alive();
293 }
294 }
295
296 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
297
298 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
299 _operation = op;
300 SafepointMechanism::arm_local_poll(target);
301 }
302
303 void HandshakeState::clear_handshake(JavaThread* target) {
304 _operation = NULL;
305 SafepointMechanism::disarm_local_poll(target);
306 }
307
308 void HandshakeState::process_self_inner(JavaThread* thread) {
309 assert(Thread::current() == thread, "should call from thread");
310
311 // If thread is not on threads list but armed, we cancel.
312 if (thread->is_terminated() && thread->has_handshake()) {
313 assert(false, "Should not happen");
314 thread->cancel_handshake();
315 return;
316 }
317
318 CautiouslyPreserveExceptionMark pem(thread);
319 ThreadInVMForHandshake tivm(thread);
320 if (!_semaphore.trywait()) {
321 _semaphore.wait_with_safepoint_check(thread);
322 }
323 HandshakeOperation* op = OrderAccess::load_acquire(&_operation);
324 if (op != NULL) {
325 // Disarm before execute the operation
326 clear_handshake(thread);
327 op->do_handshake(thread);
328 }
329 _semaphore.signal();
330 }
331
332 void HandshakeState::cancel_inner(JavaThread* thread) {
333 assert(Thread::current() == thread, "should call from thread");
334 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
335 HandshakeOperation* op = _operation;
336 clear_handshake(thread);
337 if (op != NULL) {
338 op->cancel_handshake(thread);
339 }
340 }
341
342 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
343 return SafepointSynchronize::safepoint_safe(target, target->thread_state());
344 }
345
346 bool HandshakeState::claim_handshake_for_vmthread() {
347 if (!_semaphore.trywait()) {
348 return false;
349 }
350 if (has_operation()) {
351 return true;
352 }
353 _semaphore.signal();
354 return false;
355 }
356
357 void HandshakeState::process_by_vmthread(JavaThread* target) {
358 assert(Thread::current()->is_VM_thread(), "should call from vm thread");
359
360 if (!has_operation()) {
361 // JT has already cleared its handshake
362 return;
363 }
364
365 if (!vmthread_can_process_handshake(target)) {
366 // JT is observed in an unsafe state, it must notice the handshake itself
367 return;
368 }
369
370 // If we own the semaphore at this point and while owning the semaphore
371 // can observe a safe state the thread cannot possibly continue without
372 // getting caught by the semaphore.
373 if (claim_handshake_for_vmthread()) {
374 if(!vmthread_can_process_handshake(target)) {
375 _semaphore.signal();
376 return;
377 }
378 guarantee(!_semaphore.trywait(), "we should already own the semaphore");
379
380 _operation->do_handshake(target);
381 // Disarm after VM thread have executed the operation.
382 clear_handshake(target);
383 // Release the thread
384 _semaphore.signal();
385 }
386 }
|