< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page

        

*** 43,62 **** int64_t _pending_threads; bool _executed; bool _is_direct; public: HandshakeOperation(HandshakeClosure* cl) : _handshake_cl(cl), _pending_threads(1), _executed(false), _is_direct(false) {} void do_handshake(JavaThread* thread); bool is_completed() { assert(_pending_threads >= 0, "_pending_threads cannot be negative"); return _pending_threads == 0; } void add_target_count(int count) { Atomic::add(&_pending_threads, count); } bool executed() const { return _executed; } const char* name() { return _handshake_cl->name(); } - void set_isdirect() { _is_direct = true; } bool is_direct() { return _is_direct; } #ifdef ASSERT void check_state() { assert(_pending_threads == 0, "Must be zero"); --- 43,62 ---- int64_t _pending_threads; bool _executed; bool _is_direct; public: HandshakeOperation(HandshakeClosure* cl) : _handshake_cl(cl), _pending_threads(1), _executed(false), _is_direct(false) {} + HandshakeOperation(HandshakeClosure* cl, bool is_direct) : _handshake_cl(cl), _pending_threads(1), _executed(false), _is_direct(is_direct) {} void do_handshake(JavaThread* thread); bool is_completed() { assert(_pending_threads >= 0, "_pending_threads cannot be negative"); return _pending_threads == 0; } void add_target_count(int count) { Atomic::add(&_pending_threads, count); } bool executed() const { return _executed; } const char* name() { return _handshake_cl->name(); } bool is_direct() { return _is_direct; } #ifdef ASSERT void check_state() { assert(_pending_threads == 0, "Must be zero");
*** 252,315 **** // It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation } void Handshake::execute(HandshakeClosure* thread_cl) { if (SafepointMechanism::uses_thread_local_poll()) { ! HandshakeOperation cto(thread_cl); ! VM_HandshakeAllThreads handshake(&cto); VMThread::execute(&handshake); } else { VM_HandshakeFallbackOperation op(thread_cl); VMThread::execute(&op); } } ! bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target, bool is_direct_handshake) { if (SafepointMechanism::uses_thread_local_poll()) { HandshakeOperation ho(thread_cl); ! if (is_direct_handshake) { ! direct_handshake(target, &ho); ! } else { ! VM_HandshakeOneThread op(&ho, target); ! VMThread::execute(&op); ! } ! return ho.executed(); } else { VM_HandshakeFallbackOperation op(thread_cl, target); VMThread::execute(&op); return op.executed(); } } ! void Handshake::direct_handshake(JavaThread* target, HandshakeOperation *op) { JavaThread *self = (JavaThread*)Thread::current(); ! op->set_isdirect(); jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { start_time_ns = os::javaTimeNanos(); } ThreadsListHandle tlh; if (tlh.includes(target)) { ! target->set_handshake_operation(op); } else { ! log_handshake_info(start_time_ns, op->name(), 0, 0, "(thread dead)"); ! return; } bool by_handshaker = false; ! while (!op->is_completed()) { ! by_handshaker = target->handshake_try_process(op); // Check for pending handshakes to avoid possible deadlocks where our // target is trying to handshake us. if (SafepointMechanism::should_block(self)) { ThreadBlockInVM tbivm(self); } } ! DEBUG_ONLY(op->check_state();) ! log_handshake_info(start_time_ns, op->name(), 1, by_handshaker ? 1 : 0); } HandshakeState::HandshakeState() : _operation(NULL), _operation_direct(NULL), _handshake_turn_sem(1), _processing_sem(1), _thread_in_process_handshake(false) { DEBUG_ONLY(_active_handshaker = NULL;) } --- 252,313 ---- // It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation } void Handshake::execute(HandshakeClosure* thread_cl) { if (SafepointMechanism::uses_thread_local_poll()) { ! HandshakeOperation ho(thread_cl); ! VM_HandshakeAllThreads handshake(&ho); VMThread::execute(&handshake); } else { VM_HandshakeFallbackOperation op(thread_cl); VMThread::execute(&op); } } ! bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) { if (SafepointMechanism::uses_thread_local_poll()) { HandshakeOperation ho(thread_cl); ! VM_HandshakeOneThread handshake(&ho, target); ! VMThread::execute(&handshake); ! return handshake.executed(); } else { VM_HandshakeFallbackOperation op(thread_cl, target); VMThread::execute(&op); return op.executed(); } } ! bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) { JavaThread *self = (JavaThread*)Thread::current(); ! HandshakeOperation op(thread_cl, true); jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { start_time_ns = os::javaTimeNanos(); } ThreadsListHandle tlh; if (tlh.includes(target)) { ! target->set_handshake_operation(&op); } else { ! log_handshake_info(start_time_ns, op.name(), 0, 0, "(thread dead)"); ! return false; } bool by_handshaker = false; ! while (!op.is_completed()) { ! by_handshaker = target->handshake_try_process(&op); // Check for pending handshakes to avoid possible deadlocks where our // target is trying to handshake us. if (SafepointMechanism::should_block(self)) { ThreadBlockInVM tbivm(self); } } ! DEBUG_ONLY(op.check_state();) ! log_handshake_info(start_time_ns, op.name(), 1, by_handshaker ? 1 : 0); ! ! return op.executed(); } HandshakeState::HandshakeState() : _operation(NULL), _operation_direct(NULL), _handshake_turn_sem(1), _processing_sem(1), _thread_in_process_handshake(false) { DEBUG_ONLY(_active_handshaker = NULL;) }
*** 343,365 **** do { ThreadInVMForHandshake tivm(_thread); if (!_processing_sem.trywait()) { _processing_sem.wait_with_safepoint_check(_thread); } ! bool is_direct_handshake = false; ! HandshakeOperation* op = Atomic::load_acquire(&_operation); ! if (op == NULL) { ! op = Atomic::load_acquire(&_operation_direct); ! is_direct_handshake = true; ! } ! if (op != NULL) { HandleMark hm(_thread); CautiouslyPreserveExceptionMark pem(_thread); // Disarm before execute the operation ! clear_handshake(is_direct_handshake); op->do_handshake(_thread); } _processing_sem.signal(); } while (has_operation()); } bool HandshakeState::can_process_handshake() { --- 341,366 ---- do { ThreadInVMForHandshake tivm(_thread); if (!_processing_sem.trywait()) { _processing_sem.wait_with_safepoint_check(_thread); } ! if (has_operation()) { HandleMark hm(_thread); CautiouslyPreserveExceptionMark pem(_thread); + HandshakeOperation * op = _operation; + if (op != NULL) { + // Disarm before execute the operation + clear_handshake(false); + op->do_handshake(_thread); + } + op = _operation_direct; + if (op != NULL) { // Disarm before execute the operation ! clear_handshake(true); op->do_handshake(_thread); } + } _processing_sem.signal(); } while (has_operation()); } bool HandshakeState::can_process_handshake() {
*** 391,411 **** bool HandshakeState::claim_handshake(bool is_direct) { if (!_processing_sem.trywait()) { return false; } ! if ((!is_direct && _operation != NULL) || (is_direct && _operation_direct != NULL)){ return true; } _processing_sem.signal(); return false; } bool HandshakeState::try_process(HandshakeOperation* op) { bool is_direct = op->is_direct(); ! if ((!is_direct && _operation == NULL) || (is_direct && _operation_direct == NULL)){ // JT has already cleared its handshake return false; } if (!possibly_can_process_handshake()) { --- 392,412 ---- bool HandshakeState::claim_handshake(bool is_direct) { if (!_processing_sem.trywait()) { return false; } ! if (has_specific_operation(is_direct)){ return true; } _processing_sem.signal(); return false; } bool HandshakeState::try_process(HandshakeOperation* op) { bool is_direct = op->is_direct(); ! if (!has_specific_operation(is_direct)){ // JT has already cleared its handshake return false; } if (!possibly_can_process_handshake()) {
< prev index next >