--- old/src/hotspot/share/runtime/handshake.cpp 2020-01-17 22:49:28.610839769 +0000 +++ new/src/hotspot/share/runtime/handshake.cpp 2020-01-17 22:49:27.404811137 +0000 @@ -44,12 +44,12 @@ 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) {} + HandshakeOperation(HandshakeClosure* cl, bool is_direct = false) : _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; + int64_t val = Atomic::load(&_pending_threads); + assert(val >= 0, "_pending_threads cannot be negative"); + return val == 0; } void add_target_count(int count) { Atomic::add(&_pending_threads, count); } bool executed() const { return _executed; } @@ -171,6 +171,7 @@ log_handshake_info(start_time_ns, _op->name(), 0, 0); return; } + // _op was created with a count == 1 so don't double count. _op->add_target_count(number_of_threads_issued - 1); log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThread"); @@ -282,8 +283,8 @@ VMThread::execute(&op); return op.executed(); } - JavaThread *self = (JavaThread*)Thread::current(); - HandshakeOperation op(thread_cl, true); + JavaThread *self = JavaThread::current(); + HandshakeOperation op(thread_cl, /*is_direct*/ true); jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { @@ -313,19 +314,27 @@ return op.executed(); } -HandshakeState::HandshakeState() : _operation(NULL), _operation_direct(NULL), _handshake_turn_sem(1), _processing_sem(1), _thread_in_process_handshake(false) { +HandshakeState::HandshakeState() : + _operation(NULL), + _operation_direct(NULL), + _handshake_turn_sem(1), + _processing_sem(1), + _thread_in_process_handshake(false) +{ DEBUG_ONLY(_active_handshaker = NULL;) } void HandshakeState::set_operation(HandshakeOperation* op) { if (!op->is_direct()) { + assert(Thread::current()->is_VM_thread(), "should be the VMThread"); _operation = op; } else { + assert(Thread::current()->is_Java_thread(), "should be a JavaThread"); // Serialize direct handshakes so that only one proceeds at a time for a given target - _handshake_turn_sem.wait_with_safepoint_check((JavaThread*)Thread::current()); + _handshake_turn_sem.wait_with_safepoint_check(JavaThread::current()); _operation_direct = op; } - SafepointMechanism::arm_local_poll_release(_thread); + SafepointMechanism::arm_local_poll_release(_handshakee); } void HandshakeState::clear_handshake(bool is_direct) { @@ -338,30 +347,31 @@ } void HandshakeState::process_self_inner() { - assert(Thread::current() == _thread, "should call from thread"); - assert(!_thread->is_terminated(), "should not be a terminated thread"); - assert(_thread->thread_state() != _thread_blocked, "should not be in a blocked state"); - assert(_thread->thread_state() != _thread_in_native, "should not be in native"); + assert(Thread::current() == _handshakee, "should call from _handshakee"); + assert(!_handshakee->is_terminated(), "should not be a terminated thread"); + assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state"); + assert(_handshakee->thread_state() != _thread_in_native, "should not be in native"); + JavaThread* self = _handshakee; do { - ThreadInVMForHandshake tivm(_thread); + ThreadInVMForHandshake tivm(self); if (!_processing_sem.trywait()) { - _processing_sem.wait_with_safepoint_check(_thread); + _processing_sem.wait_with_safepoint_check(self); } if (has_operation()) { - HandleMark hm(_thread); - CautiouslyPreserveExceptionMark pem(_thread); + HandleMark hm(self); + CautiouslyPreserveExceptionMark pem(self); HandshakeOperation * op = _operation; if (op != NULL) { - // Disarm before execute the operation - clear_handshake(false); - op->do_handshake(_thread); + // Disarm before executing the operation + clear_handshake( /*is_direct*/ false); + op->do_handshake(self); } op = _operation_direct; if (op != NULL) { - // Disarm before execute the operation - clear_handshake(true); - op->do_handshake(_thread); + // Disarm before executing the operation + clear_handshake( /*is_direct*/ true); + op->do_handshake(self); } } _processing_sem.signal(); @@ -371,21 +381,21 @@ bool HandshakeState::can_process_handshake() { // handshake_safe may only be called with polls armed. // Handshaker controls this by first claiming the handshake via claim_handshake(). - return SafepointSynchronize::handshake_safe(_thread); + return SafepointSynchronize::handshake_safe(_handshakee); } bool HandshakeState::possibly_can_process_handshake() { // Note that this method is allowed to produce false positives. - if (_thread->is_ext_suspended()) { + if (_handshakee->is_ext_suspended()) { return true; } - if (_thread->is_terminated()) { + if (_handshakee->is_terminated()) { return true; } - switch (_thread->thread_state()) { + switch (_handshakee->thread_state()) { case _thread_in_native: // native threads are safe if they have no java stack or have walkable stack - return !_thread->has_last_Java_frame() || _thread->frame_anchor()->walkable(); + return !_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(); case _thread_blocked: return true; @@ -440,7 +450,7 @@ guarantee(!_processing_sem.trywait(), "we should already own the semaphore"); log_trace(handshake)("Processing handshake by %s", Thread::current()->is_VM_thread() ? "VMThread" : "Handshaker"); DEBUG_ONLY(_active_handshaker = Thread::current();) - op->do_handshake(_thread); + op->do_handshake(_handshakee); DEBUG_ONLY(_active_handshaker = NULL;) // Disarm after we have executed the operation. clear_handshake(is_direct);