< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page

        

*** 42,57 **** HandshakeClosure* _handshake_cl; 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(); } --- 42,57 ---- HandshakeClosure* _handshake_cl; int64_t _pending_threads; bool _executed; bool _is_direct; public: ! 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() { ! 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; } const char* name() { return _handshake_cl->name(); }
*** 169,178 **** --- 169,179 ---- if (number_of_threads_issued < 1) { 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"); const jlong start_time = os::elapsed_counter(); do {
*** 280,291 **** if (!SafepointMechanism::uses_thread_local_poll()) { VM_HandshakeFallbackOperation op(thread_cl, target); VMThread::execute(&op); return op.executed(); } ! 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(); } --- 281,292 ---- if (!SafepointMechanism::uses_thread_local_poll()) { VM_HandshakeFallbackOperation op(thread_cl, target); VMThread::execute(&op); return op.executed(); } ! JavaThread *self = JavaThread::current(); ! HandshakeOperation op(thread_cl, /*is_direct*/ true); jlong start_time_ns = 0; if (log_is_enabled(Info, handshake)) { start_time_ns = os::javaTimeNanos(); }
*** 311,333 **** 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;) } void HandshakeState::set_operation(HandshakeOperation* op) { if (!op->is_direct()) { _operation = op; } else { // 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()); _operation_direct = op; } ! SafepointMechanism::arm_local_poll_release(_thread); } void HandshakeState::clear_handshake(bool is_direct) { if (!is_direct) { _operation = NULL; --- 312,342 ---- 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;) } 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::current()); _operation_direct = op; } ! SafepointMechanism::arm_local_poll_release(_handshakee); } void HandshakeState::clear_handshake(bool is_direct) { if (!is_direct) { _operation = NULL;
*** 336,393 **** _handshake_turn_sem.signal(); } } 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"); 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() { // 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); } bool HandshakeState::possibly_can_process_handshake() { // Note that this method is allowed to produce false positives. ! if (_thread->is_ext_suspended()) { return true; } ! if (_thread->is_terminated()) { return true; } ! switch (_thread->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(); case _thread_blocked: return true; default: --- 345,403 ---- _handshake_turn_sem.signal(); } } void HandshakeState::process_self_inner() { ! 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(self); if (!_processing_sem.trywait()) { ! _processing_sem.wait_with_safepoint_check(self); } if (has_operation()) { ! HandleMark hm(self); ! CautiouslyPreserveExceptionMark pem(self); HandshakeOperation * op = _operation; if (op != NULL) { ! // Disarm before executing the operation ! clear_handshake( /*is_direct*/ false); ! op->do_handshake(self); } op = _operation_direct; if (op != NULL) { ! // Disarm before executing the operation ! clear_handshake( /*is_direct*/ true); ! op->do_handshake(self); } } _processing_sem.signal(); } while (has_operation()); } 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(_handshakee); } bool HandshakeState::possibly_can_process_handshake() { // Note that this method is allowed to produce false positives. ! if (_handshakee->is_ext_suspended()) { return true; } ! if (_handshakee->is_terminated()) { return true; } ! switch (_handshakee->thread_state()) { case _thread_in_native: // native threads are safe if they have no java stack or have walkable stack ! return !_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(); case _thread_blocked: return true; default:
*** 438,448 **** bool executed = false; if (can_process_handshake()) { 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); DEBUG_ONLY(_active_handshaker = NULL;) // Disarm after we have executed the operation. clear_handshake(is_direct); executed = true; } --- 448,458 ---- bool executed = false; if (can_process_handshake()) { 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(_handshakee); DEBUG_ONLY(_active_handshaker = NULL;) // Disarm after we have executed the operation. clear_handshake(is_direct); executed = true; }
< prev index next >