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 } |
135 |
135 |
136 // We need to re-think this with SMR ThreadsList. |
136 // We need to re-think this with SMR ThreadsList. |
137 // There is an assumption in the code that the Threads_lock should be |
137 // There is an assumption in the code that the Threads_lock should be |
138 // locked during certain phases. |
138 // locked during certain phases. |
139 { |
139 { |
140 MutexLocker ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
140 MutexLocker ml(Threads_lock); |
141 _target->handshake_process_by_vmthread(); |
141 _target->handshake_process_by_vmthread(); |
142 } |
142 } |
143 } while (!poll_for_completed_thread()); |
143 } while (!poll_for_completed_thread()); |
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); |
184 { |
184 { |
185 // We need to re-think this with SMR ThreadsList. |
185 // We need to re-think this with SMR ThreadsList. |
186 // There is an assumption in the code that the Threads_lock should |
186 // There is an assumption in the code that the Threads_lock should |
187 // be locked during certain phases. |
187 // be locked during certain phases. |
188 jtiwh.rewind(); |
188 jtiwh.rewind(); |
189 MutexLocker ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
189 MutexLocker ml(Threads_lock); |
190 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
190 for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
191 // A new thread on the ThreadsList will not have an operation, |
191 // A new thread on the ThreadsList will not have an operation, |
192 // hence it is skipped in handshake_process_by_vmthread. |
192 // hence it is skipped in handshake_process_by_vmthread. |
193 thr->handshake_process_by_vmthread(); |
193 thr->handshake_process_by_vmthread(); |
194 } |
194 } |
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", |
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 } |