44 }; |
44 }; |
45 |
45 |
46 class HandshakeThreadsOperation: public HandshakeOperation { |
46 class HandshakeThreadsOperation: public HandshakeOperation { |
47 static Semaphore _done; |
47 static Semaphore _done; |
48 ThreadClosure* _thread_cl; |
48 ThreadClosure* _thread_cl; |
49 |
49 bool _executed; |
50 public: |
50 public: |
51 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {} |
51 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {} |
52 void do_handshake(JavaThread* thread); |
52 void do_handshake(JavaThread* thread); |
53 bool thread_has_completed() { return _done.trywait(); } |
53 bool thread_has_completed() { return _done.trywait(); } |
|
54 bool executed() const { return _executed; } |
54 |
55 |
55 #ifdef ASSERT |
56 #ifdef ASSERT |
56 void check_state() { |
57 void check_state() { |
57 assert(!_done.trywait(), "Must be zero"); |
58 assert(!_done.trywait(), "Must be zero"); |
58 } |
59 } |
107 fatal("Handshake operation timed out"); |
108 fatal("Handshake operation timed out"); |
108 } |
109 } |
109 |
110 |
110 class VM_HandshakeOneThread: public VM_Handshake { |
111 class VM_HandshakeOneThread: public VM_Handshake { |
111 JavaThread* _target; |
112 JavaThread* _target; |
112 bool _thread_alive; |
|
113 public: |
113 public: |
114 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) : |
114 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) : |
115 VM_Handshake(op), _target(target), _thread_alive(false) {} |
115 VM_Handshake(op), _target(target) {} |
116 |
116 |
117 void doit() { |
117 void doit() { |
118 DEBUG_ONLY(_op->check_state();) |
118 DEBUG_ONLY(_op->check_state();) |
119 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
119 TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake)); |
120 |
120 |
121 ThreadsListHandle tlh; |
121 ThreadsListHandle tlh; |
122 if (tlh.includes(_target)) { |
122 if (tlh.includes(_target)) { |
123 set_handshake(_target); |
123 set_handshake(_target); |
124 _thread_alive = true; |
|
125 } else { |
124 } else { |
|
125 log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target)); |
126 return; |
126 return; |
127 } |
127 } |
128 |
128 |
129 log_trace(handshake)("Thread signaled, begin processing by VMThtread"); |
129 log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target)); |
130 jlong start_time = os::elapsed_counter(); |
130 jlong start_time = os::elapsed_counter(); |
131 do { |
131 do { |
132 if (handshake_has_timed_out(start_time)) { |
132 if (handshake_has_timed_out(start_time)) { |
133 handle_timeout(); |
133 handle_timeout(); |
134 } |
134 } |
144 DEBUG_ONLY(_op->check_state();) |
144 DEBUG_ONLY(_op->check_state();) |
145 } |
145 } |
146 |
146 |
147 VMOp_Type type() const { return VMOp_HandshakeOneThread; } |
147 VMOp_Type type() const { return VMOp_HandshakeOneThread; } |
148 |
148 |
149 bool thread_alive() const { return _thread_alive; } |
149 bool executed() const { return _op->executed(); } |
150 }; |
150 }; |
151 |
151 |
152 class VM_HandshakeAllThreads: public VM_Handshake { |
152 class VM_HandshakeAllThreads: public VM_Handshake { |
153 public: |
153 public: |
154 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} |
154 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} |
155 |
155 |
156 void doit() { |
156 void doit() { |
157 DEBUG_ONLY(_op->check_state();) |
157 DEBUG_ONLY(_op->check_state();) |
158 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); |
158 TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake)); |
159 |
159 |
160 JavaThreadIteratorWithHandle jtiwh; |
160 JavaThreadIteratorWithHandle jtiwh; |
161 int number_of_threads_issued = 0; |
161 int number_of_threads_issued = 0; |
162 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
162 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
163 set_handshake(thr); |
163 set_handshake(thr); |
209 |
209 |
210 class VM_HandshakeFallbackOperation : public VM_Operation { |
210 class VM_HandshakeFallbackOperation : public VM_Operation { |
211 ThreadClosure* _thread_cl; |
211 ThreadClosure* _thread_cl; |
212 Thread* _target_thread; |
212 Thread* _target_thread; |
213 bool _all_threads; |
213 bool _all_threads; |
214 bool _thread_alive; |
214 bool _executed; |
215 public: |
215 public: |
216 VM_HandshakeFallbackOperation(ThreadClosure* cl) : |
216 VM_HandshakeFallbackOperation(ThreadClosure* cl) : |
217 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {} |
217 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {} |
218 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : |
218 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : |
219 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {} |
219 _thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {} |
220 |
220 |
221 void doit() { |
221 void doit() { |
|
222 log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation"); |
222 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
223 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
223 if (_all_threads || t == _target_thread) { |
224 if (_all_threads || t == _target_thread) { |
224 if (t == _target_thread) { |
225 if (t == _target_thread) { |
225 _thread_alive = true; |
226 _executed = true; |
226 } |
227 } |
227 _thread_cl->do_thread(t); |
228 _thread_cl->do_thread(t); |
228 } |
229 } |
229 } |
230 } |
230 } |
231 } |
231 |
232 |
232 VMOp_Type type() const { return VMOp_HandshakeFallback; } |
233 VMOp_Type type() const { return VMOp_HandshakeFallback; } |
233 bool thread_alive() const { return _thread_alive; } |
234 bool executed() const { return _executed; } |
234 }; |
235 }; |
235 |
236 |
236 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
237 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
237 ResourceMark rm; |
238 ResourceMark rm; |
238 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s", |
239 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s", |
240 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
241 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
241 |
242 |
242 // Only actually execute the operation for non terminated threads. |
243 // Only actually execute the operation for non terminated threads. |
243 if (!thread->is_terminated()) { |
244 if (!thread->is_terminated()) { |
244 _thread_cl->do_thread(thread); |
245 _thread_cl->do_thread(thread); |
|
246 _executed = true; |
245 } |
247 } |
246 |
248 |
247 // Use the semaphore to inform the VM thread that we have completed the operation |
249 // Use the semaphore to inform the VM thread that we have completed the operation |
248 _done.signal(); |
250 _done.signal(); |
249 } |
251 } |
262 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) { |
264 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) { |
263 if (ThreadLocalHandshakes) { |
265 if (ThreadLocalHandshakes) { |
264 HandshakeThreadsOperation cto(thread_cl); |
266 HandshakeThreadsOperation cto(thread_cl); |
265 VM_HandshakeOneThread handshake(&cto, target); |
267 VM_HandshakeOneThread handshake(&cto, target); |
266 VMThread::execute(&handshake); |
268 VMThread::execute(&handshake); |
267 return handshake.thread_alive(); |
269 return handshake.executed(); |
268 } else { |
270 } else { |
269 VM_HandshakeFallbackOperation op(thread_cl, target); |
271 VM_HandshakeFallbackOperation op(thread_cl, target); |
270 VMThread::execute(&op); |
272 VMThread::execute(&op); |
271 return op.thread_alive(); |
273 return op.executed(); |
272 } |
274 } |
273 } |
275 } |
274 |
276 |
275 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {} |
277 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {} |
276 |
278 |
367 // If we own the semaphore at this point and while owning the semaphore |
369 // If we own the semaphore at this point and while owning the semaphore |
368 // can observe a safe state the thread cannot possibly continue without |
370 // can observe a safe state the thread cannot possibly continue without |
369 // getting caught by the semaphore. |
371 // getting caught by the semaphore. |
370 if (vmthread_can_process_handshake(target)) { |
372 if (vmthread_can_process_handshake(target)) { |
371 guarantee(!_semaphore.trywait(), "we should already own the semaphore"); |
373 guarantee(!_semaphore.trywait(), "we should already own the semaphore"); |
|
374 log_trace(handshake)("Processing handshake by VMThtread"); |
372 _operation->do_handshake(target); |
375 _operation->do_handshake(target); |
373 // Disarm after VM thread have executed the operation. |
376 // Disarm after VM thread have executed the operation. |
374 clear_handshake(target); |
377 clear_handshake(target); |
375 // Release the thread |
378 // Release the thread |
376 } |
379 } |