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