28 #include "memory/resourceArea.hpp"
29 #include "runtime/atomic.hpp"
30 #include "runtime/handshake.hpp"
31 #include "runtime/interfaceSupport.inline.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 };
45
46 class HandshakeThreadsOperation: public HandshakeOperation {
47 static Semaphore _done;
48 ThreadClosure* _thread_cl;
49 bool _executed;
50 public:
51 HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {}
52 void do_handshake(JavaThread* thread);
53 bool thread_has_completed() { return _done.trywait(); }
54 bool executed() const { return _executed; }
55
56 #ifdef ASSERT
57 void check_state() {
58 assert(!_done.trywait(), "Must be zero");
59 }
60 #endif
61 };
62
63 Semaphore HandshakeThreadsOperation::_done(0);
64
65 class VM_Handshake: public VM_Operation {
66 const jlong _handshake_timeout;
67 public:
68 bool evaluate_at_safepoint() const { return false; }
69
70 bool evaluate_concurrently() const { return false; }
71
191 // A new thread on the ThreadsList will not have an operation,
192 // hence it is skipped in handshake_process_by_vmthread.
193 thr->handshake_process_by_vmthread();
194 }
195 }
196
197 while (poll_for_completed_thread()) {
198 // Includes canceled operations by exiting threads.
199 number_of_threads_completed++;
200 }
201
202 } while (number_of_threads_issued > number_of_threads_completed);
203 assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
204 DEBUG_ONLY(_op->check_state();)
205 }
206
207 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
208 };
209
210 class VM_HandshakeFallbackOperation : public VM_Operation {
211 ThreadClosure* _thread_cl;
212 Thread* _target_thread;
213 bool _all_threads;
214 bool _executed;
215 public:
216 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
217 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
218 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
219 _thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
220
221 void doit() {
222 log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
223 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
224 if (_all_threads || t == _target_thread) {
225 if (t == _target_thread) {
226 _executed = true;
227 }
228 _thread_cl->do_thread(t);
229 }
230 }
231 }
232
233 VMOp_Type type() const { return VMOp_HandshakeFallback; }
234 bool executed() const { return _executed; }
235 };
236
237 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
238 ResourceMark rm;
239 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
240 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
241 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
242
243 // Only actually execute the operation for non terminated threads.
244 if (!thread->is_terminated()) {
245 _thread_cl->do_thread(thread);
246 _executed = true;
247 }
248
249 // Use the semaphore to inform the VM thread that we have completed the operation
250 _done.signal();
251 }
252
253 void Handshake::execute(ThreadClosure* thread_cl) {
254 if (ThreadLocalHandshakes) {
255 HandshakeThreadsOperation cto(thread_cl);
256 VM_HandshakeAllThreads handshake(&cto);
257 VMThread::execute(&handshake);
258 } else {
259 VM_HandshakeFallbackOperation op(thread_cl);
260 VMThread::execute(&op);
261 }
262 }
263
264 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
265 if (ThreadLocalHandshakes) {
266 HandshakeThreadsOperation cto(thread_cl);
267 VM_HandshakeOneThread handshake(&cto, target);
268 VMThread::execute(&handshake);
269 return handshake.executed();
270 } else {
271 VM_HandshakeFallbackOperation op(thread_cl, target);
272 VMThread::execute(&op);
273 return op.executed();
274 }
275 }
276
277 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
278
279 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
280 _operation = op;
281 SafepointMechanism::arm_local_poll_release(target);
282 }
283
284 void HandshakeState::clear_handshake(JavaThread* target) {
|
28 #include "memory/resourceArea.hpp"
29 #include "runtime/atomic.hpp"
30 #include "runtime/handshake.hpp"
31 #include "runtime/interfaceSupport.inline.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 };
45
46 class HandshakeThreadsOperation: public HandshakeOperation {
47 static Semaphore _done;
48 HandshakeClosure* _handshake_cl;
49 bool _executed;
50 public:
51 HandshakeThreadsOperation(HandshakeClosure* cl) : _handshake_cl(cl), _executed(false) {}
52 void do_handshake(JavaThread* thread);
53 bool thread_has_completed() { return _done.trywait(); }
54 bool executed() const { return _executed; }
55
56 #ifdef ASSERT
57 void check_state() {
58 assert(!_done.trywait(), "Must be zero");
59 }
60 #endif
61 };
62
63 Semaphore HandshakeThreadsOperation::_done(0);
64
65 class VM_Handshake: public VM_Operation {
66 const jlong _handshake_timeout;
67 public:
68 bool evaluate_at_safepoint() const { return false; }
69
70 bool evaluate_concurrently() const { return false; }
71
191 // A new thread on the ThreadsList will not have an operation,
192 // hence it is skipped in handshake_process_by_vmthread.
193 thr->handshake_process_by_vmthread();
194 }
195 }
196
197 while (poll_for_completed_thread()) {
198 // Includes canceled operations by exiting threads.
199 number_of_threads_completed++;
200 }
201
202 } while (number_of_threads_issued > number_of_threads_completed);
203 assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
204 DEBUG_ONLY(_op->check_state();)
205 }
206
207 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
208 };
209
210 class VM_HandshakeFallbackOperation : public VM_Operation {
211 HandshakeClosure* _handshake_cl;
212 Thread* _target_thread;
213 bool _all_threads;
214 bool _executed;
215 public:
216 VM_HandshakeFallbackOperation(HandshakeClosure* cl) :
217 _handshake_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
218 VM_HandshakeFallbackOperation(HandshakeClosure* cl, Thread* target) :
219 _handshake_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
220
221 void doit() {
222 log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
223 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
224 if (_all_threads || t == _target_thread) {
225 if (t == _target_thread) {
226 _executed = true;
227 }
228 _handshake_cl->do_thread(t);
229 }
230 }
231 }
232
233 VMOp_Type type() const { return VMOp_HandshakeFallback; }
234 bool executed() const { return _executed; }
235 };
236
237 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
238 ResourceMark rm;
239 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
240 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
241 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
242
243 // Only actually execute the operation for non terminated threads.
244 if (!thread->is_terminated()) {
245 _handshake_cl->do_thread(thread);
246 _executed = true;
247 }
248
249 // Use the semaphore to inform the VM thread that we have completed the operation
250 _done.signal();
251 }
252
253 void Handshake::execute(HandshakeClosure* thread_cl) {
254 if (ThreadLocalHandshakes) {
255 HandshakeThreadsOperation cto(thread_cl);
256 VM_HandshakeAllThreads handshake(&cto);
257 VMThread::execute(&handshake);
258 } else {
259 VM_HandshakeFallbackOperation op(thread_cl);
260 VMThread::execute(&op);
261 }
262 }
263
264 bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) {
265 if (ThreadLocalHandshakes) {
266 HandshakeThreadsOperation cto(thread_cl);
267 VM_HandshakeOneThread handshake(&cto, target);
268 VMThread::execute(&handshake);
269 return handshake.executed();
270 } else {
271 VM_HandshakeFallbackOperation op(thread_cl, target);
272 VMThread::execute(&op);
273 return op.executed();
274 }
275 }
276
277 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
278
279 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
280 _operation = op;
281 SafepointMechanism::arm_local_poll_release(target);
282 }
283
284 void HandshakeState::clear_handshake(JavaThread* target) {
|