39 #include "utilities/preserveException.hpp" |
39 #include "utilities/preserveException.hpp" |
40 |
40 |
41 class HandshakeOperation: public StackObj { |
41 class HandshakeOperation: public StackObj { |
42 public: |
42 public: |
43 virtual void do_handshake(JavaThread* thread) = 0; |
43 virtual void do_handshake(JavaThread* thread) = 0; |
44 virtual void cancel_handshake(JavaThread* thread) = 0; |
|
45 }; |
44 }; |
46 |
45 |
47 class HandshakeThreadsOperation: public HandshakeOperation { |
46 class HandshakeThreadsOperation: public HandshakeOperation { |
48 static Semaphore _done; |
47 static Semaphore _done; |
49 ThreadClosure* _thread_cl; |
48 ThreadClosure* _thread_cl; |
50 |
49 |
51 public: |
50 public: |
52 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {} |
51 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {} |
53 void do_handshake(JavaThread* thread); |
52 void do_handshake(JavaThread* thread); |
54 void cancel_handshake(JavaThread* thread) { _done.signal(); }; |
|
55 |
|
56 bool thread_has_completed() { return _done.trywait(); } |
53 bool thread_has_completed() { return _done.trywait(); } |
57 |
54 |
58 #ifdef ASSERT |
55 #ifdef ASSERT |
59 void check_state() { |
56 void check_state() { |
60 assert(!_done.trywait(), "Must be zero"); |
57 assert(!_done.trywait(), "Must be zero"); |
119 |
116 |
120 void doit() { |
117 void doit() { |
121 DEBUG_ONLY(_op->check_state();) |
118 DEBUG_ONLY(_op->check_state();) |
122 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
119 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
123 |
120 |
124 { |
121 ThreadsListHandle tlh; |
125 ThreadsListHandle tlh; |
122 if (tlh.includes(_target)) { |
126 if (tlh.includes(_target)) { |
123 set_handshake(_target); |
127 set_handshake(_target); |
124 _thread_alive = true; |
128 _thread_alive = true; |
125 } else { |
129 } |
|
130 } |
|
131 |
|
132 if (!_thread_alive) { |
|
133 return; |
126 return; |
134 } |
127 } |
135 |
128 |
136 if (!UseMembar) { |
129 if (!UseMembar) { |
137 os::serialize_thread_states(); |
130 os::serialize_thread_states(); |
145 } |
138 } |
146 |
139 |
147 // We need to re-think this with SMR ThreadsList. |
140 // We need to re-think this with SMR ThreadsList. |
148 // There is an assumption in the code that the Threads_lock should be |
141 // There is an assumption in the code that the Threads_lock should be |
149 // locked during certain phases. |
142 // locked during certain phases. |
150 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
143 { |
151 ThreadsListHandle tlh; |
144 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
152 if (tlh.includes(_target)) { |
|
153 // Warning _target's address might be re-used. |
|
154 // handshake_process_by_vmthread will check the semaphore for us again. |
|
155 // Since we can't have more then one handshake in flight a reuse of |
|
156 // _target's address should be okay since the new thread will not have |
|
157 // an operation. |
|
158 _target->handshake_process_by_vmthread(); |
145 _target->handshake_process_by_vmthread(); |
159 } else { |
|
160 // We can't warn here since the thread does cancel_handshake after |
|
161 // it has been removed from the ThreadsList. So we should just keep |
|
162 // looping here until while below returns false. If we have a bug, |
|
163 // then we hang here, which is good for debugging. |
|
164 } |
146 } |
165 } while (!poll_for_completed_thread()); |
147 } while (!poll_for_completed_thread()); |
166 DEBUG_ONLY(_op->check_state();) |
148 DEBUG_ONLY(_op->check_state();) |
167 } |
149 } |
168 |
150 |
177 |
159 |
178 void doit() { |
160 void doit() { |
179 DEBUG_ONLY(_op->check_state();) |
161 DEBUG_ONLY(_op->check_state();) |
180 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
162 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
181 |
163 |
|
164 JavaThreadIteratorWithHandle jtiwh; |
182 int number_of_threads_issued = 0; |
165 int number_of_threads_issued = 0; |
183 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { |
166 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
184 set_handshake(thr); |
167 set_handshake(thr); |
185 number_of_threads_issued++; |
168 number_of_threads_issued++; |
186 } |
169 } |
187 |
170 |
188 if (number_of_threads_issued < 1) { |
171 if (number_of_threads_issued < 1) { |
208 // by semaphores and we optimistically begin by working on the blocked threads |
191 // by semaphores and we optimistically begin by working on the blocked threads |
209 { |
192 { |
210 // We need to re-think this with SMR ThreadsList. |
193 // We need to re-think this with SMR ThreadsList. |
211 // There is an assumption in the code that the Threads_lock should |
194 // There is an assumption in the code that the Threads_lock should |
212 // be locked during certain phases. |
195 // be locked during certain phases. |
|
196 jtiwh.rewind(); |
213 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
197 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
214 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { |
198 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
215 // A new thread on the ThreadsList will not have an operation, |
199 // A new thread on the ThreadsList will not have an operation, |
216 // hence it is skipped in handshake_process_by_vmthread. |
200 // hence it is skipped in handshake_process_by_vmthread. |
217 thr->handshake_process_by_vmthread(); |
201 thr->handshake_process_by_vmthread(); |
218 } |
202 } |
219 } |
203 } |
260 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
244 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
261 ResourceMark rm; |
245 ResourceMark rm; |
262 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s", |
246 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s", |
263 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread())); |
247 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread())); |
264 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
248 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
265 _thread_cl->do_thread(thread); |
249 |
|
250 // Only actually execute the operation for non terminated threads. |
|
251 if (!thread->is_terminated()) { |
|
252 _thread_cl->do_thread(thread); |
|
253 } |
266 |
254 |
267 // Use the semaphore to inform the VM thread that we have completed the operation |
255 // Use the semaphore to inform the VM thread that we have completed the operation |
268 _done.signal(); |
256 _done.signal(); |
269 } |
257 } |
270 |
258 |
304 SafepointMechanism::disarm_local_poll_release(target); |
292 SafepointMechanism::disarm_local_poll_release(target); |
305 } |
293 } |
306 |
294 |
307 void HandshakeState::process_self_inner(JavaThread* thread) { |
295 void HandshakeState::process_self_inner(JavaThread* thread) { |
308 assert(Thread::current() == thread, "should call from thread"); |
296 assert(Thread::current() == thread, "should call from thread"); |
309 |
297 assert(!thread->is_terminated(), "should not be a terminated thread"); |
310 if (thread->is_terminated()) { |
|
311 // If thread is not on threads list but armed, cancel. |
|
312 thread->cancel_handshake(); |
|
313 return; |
|
314 } |
|
315 |
298 |
316 CautiouslyPreserveExceptionMark pem(thread); |
299 CautiouslyPreserveExceptionMark pem(thread); |
317 ThreadInVMForHandshake tivm(thread); |
300 ThreadInVMForHandshake tivm(thread); |
318 if (!_semaphore.trywait()) { |
301 if (!_semaphore.trywait()) { |
319 _semaphore.wait_with_safepoint_check(thread); |
302 _semaphore.wait_with_safepoint_check(thread); |
323 // Disarm before execute the operation |
306 // Disarm before execute the operation |
324 clear_handshake(thread); |
307 clear_handshake(thread); |
325 op->do_handshake(thread); |
308 op->do_handshake(thread); |
326 } |
309 } |
327 _semaphore.signal(); |
310 _semaphore.signal(); |
328 } |
|
329 |
|
330 void HandshakeState::cancel_inner(JavaThread* thread) { |
|
331 assert(Thread::current() == thread, "should call from thread"); |
|
332 assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); |
|
333 HandshakeOperation* op = _operation; |
|
334 clear_handshake(thread); |
|
335 if (op != NULL) { |
|
336 op->cancel_handshake(thread); |
|
337 } |
|
338 } |
311 } |
339 |
312 |
340 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) { |
313 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) { |
341 // SafepointSynchronize::safepoint_safe() does not consider an externally |
314 // SafepointSynchronize::safepoint_safe() does not consider an externally |
342 // suspended thread to be safe. However, this function must be called with |
315 // suspended thread to be safe. However, this function must be called with |
343 // the Threads_lock held so an externally suspended thread cannot be |
316 // the Threads_lock held so an externally suspended thread cannot be |
344 // resumed thus it is safe. |
317 // resumed thus it is safe. |
345 assert(Threads_lock->owned_by_self(), "Not holding Threads_lock."); |
318 assert(Threads_lock->owned_by_self(), "Not holding Threads_lock."); |
346 return SafepointSynchronize::safepoint_safe(target, target->thread_state()) || |
319 return SafepointSynchronize::safepoint_safe(target, target->thread_state()) || |
347 target->is_ext_suspended(); |
320 target->is_ext_suspended() || target->is_terminated(); |
348 } |
321 } |
349 |
322 |
350 static bool possibly_vmthread_can_process_handshake(JavaThread* target) { |
323 static bool possibly_vmthread_can_process_handshake(JavaThread* target) { |
351 // An externally suspended thread cannot be resumed while the |
324 // An externally suspended thread cannot be resumed while the |
352 // Threads_lock is held so it is safe. |
325 // Threads_lock is held so it is safe. |
353 // Note that this method is allowed to produce false positives. |
326 // Note that this method is allowed to produce false positives. |
354 assert(Threads_lock->owned_by_self(), "Not holding Threads_lock."); |
327 assert(Threads_lock->owned_by_self(), "Not holding Threads_lock."); |
355 if (target->is_ext_suspended()) { |
328 if (target->is_ext_suspended()) { |
356 return true; |
329 return true; |
357 } |
330 } |
|
331 if (target->is_terminated()) { |
|
332 return true; |
|
333 } |
358 switch (target->thread_state()) { |
334 switch (target->thread_state()) { |
359 case _thread_in_native: |
335 case _thread_in_native: |
360 // native threads are safe if they have no java stack or have walkable stack |
336 // native threads are safe if they have no java stack or have walkable stack |
361 return !target->has_last_Java_frame() || target->frame_anchor()->walkable(); |
337 return !target->has_last_Java_frame() || target->frame_anchor()->walkable(); |
362 |
338 |
379 return false; |
355 return false; |
380 } |
356 } |
381 |
357 |
382 void HandshakeState::process_by_vmthread(JavaThread* target) { |
358 void HandshakeState::process_by_vmthread(JavaThread* target) { |
383 assert(Thread::current()->is_VM_thread(), "should call from vm thread"); |
359 assert(Thread::current()->is_VM_thread(), "should call from vm thread"); |
|
360 // Threads_lock must be held here, but that is assert()ed in |
|
361 // possibly_vmthread_can_process_handshake(). |
384 |
362 |
385 if (!has_operation()) { |
363 if (!has_operation()) { |
386 // JT has already cleared its handshake |
364 // JT has already cleared its handshake |
387 return; |
365 return; |
388 } |
366 } |
400 // If we own the semaphore at this point and while owning the semaphore |
378 // If we own the semaphore at this point and while owning the semaphore |
401 // can observe a safe state the thread cannot possibly continue without |
379 // can observe a safe state the thread cannot possibly continue without |
402 // getting caught by the semaphore. |
380 // getting caught by the semaphore. |
403 if (vmthread_can_process_handshake(target)) { |
381 if (vmthread_can_process_handshake(target)) { |
404 guarantee(!_semaphore.trywait(), "we should already own the semaphore"); |
382 guarantee(!_semaphore.trywait(), "we should already own the semaphore"); |
405 |
|
406 _operation->do_handshake(target); |
383 _operation->do_handshake(target); |
407 // Disarm after VM thread have executed the operation. |
384 // Disarm after VM thread have executed the operation. |
408 clear_handshake(target); |
385 clear_handshake(target); |
409 // Release the thread |
386 // Release the thread |
410 } |
387 } |