< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 47820 : imported patch 10.08.open.rebase_20171114.rehn

*** 35,46 **** #include "runtime/thread.hpp" #include "runtime/vmThread.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/preserveException.hpp" - #define ALL_JAVA_THREADS(X) for (JavaThread* X = Threads::first(); X; X = X->next()) - class HandshakeOperation: public StackObj { public: virtual void do_handshake(JavaThread* thread) = 0; virtual void cancel_handshake(JavaThread* thread) = 0; }; --- 35,44 ----
*** 92,103 **** return false; } void VM_Handshake::handle_timeout() { LogStreamHandle(Warning, handshake) log_stream; ! MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! ALL_JAVA_THREADS(thr) { if (thr->has_handshake()) { log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr)); thr->print_thread_state_on(&log_stream); } } --- 90,100 ---- return false; } void VM_Handshake::handle_timeout() { LogStreamHandle(Warning, handshake) log_stream; ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { if (thr->has_handshake()) { log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr)); thr->print_thread_state_on(&log_stream); } }
*** 115,126 **** void doit() { TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); { ! MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! if (Threads::includes(_target)) { set_handshake(_target); _thread_alive = true; } } --- 112,123 ---- void doit() { TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); { ! ThreadsListHandle tlh; ! if (tlh.includes(_target)) { set_handshake(_target); _thread_alive = true; } }
*** 137,148 **** --- 134,159 ---- do { if (handshake_has_timed_out(start_time)) { handle_timeout(); } + // We need to re-think this with SMR ThreadsList. + // There is assumption in code that Threads_lock should be lock + // during certain phases. MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); + ThreadsListHandle tlh; + if (tlh.includes(_target)) { + // Warning threads address might be re-used. + // handshake_process_by_vmthread will check the semaphore for us again + // Since we can't have more then one handshake in flight a reuse of thread address + // should be okey since the new thread will not have an operation. _target->handshake_process_by_vmthread(); + } else { + // We can't warn here is since the thread do cancel_handshake after it have been removed + // from ThreadsList. So we should just keep looping here until while below return negative + // If we have a bug, then we deadlock here, which is good for debugging. + } } while (!poll_for_completed_thread()); } VMOp_Type type() const { return VMOp_HandshakeOneThread; }
*** 155,181 **** VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} void doit() { TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); ! int number_of_threads_issued = -1; ! int number_of_threads_completed = 0; ! { ! MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! number_of_threads_issued = Threads::number_of_threads(); ! ! ALL_JAVA_THREADS(thr) { set_handshake(thr); } } if (!UseMembar) { os::serialize_thread_states(); } log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread"); const jlong start_time = os::elapsed_counter(); do { // Check if handshake operation has timed out if (handshake_has_timed_out(start_time)) { handle_timeout(); } --- 166,193 ---- VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} void doit() { TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake)); ! int number_of_threads_issued = 0; ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { set_handshake(thr); + number_of_threads_issued++; } + + if (number_of_threads_issued < 1) { + log_debug(handshake)("No threads to handshake."); + return; } if (!UseMembar) { os::serialize_thread_states(); } log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread"); const jlong start_time = os::elapsed_counter(); + int number_of_threads_completed = 0; do { // Check if handshake operation has timed out if (handshake_has_timed_out(start_time)) { handle_timeout(); }
*** 182,198 **** // Have VM thread perform the handshake operation for blocked threads. // Observing a blocked state may of course be transient but the processing is guarded // by semaphores and we optimistically begin by working on the blocked threads { MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! ALL_JAVA_THREADS(thr) { thr->handshake_process_by_vmthread(); } } while (poll_for_completed_thread()) { number_of_threads_completed++; } } while (number_of_threads_issued != number_of_threads_completed); } --- 194,216 ---- // Have VM thread perform the handshake operation for blocked threads. // Observing a blocked state may of course be transient but the processing is guarded // by semaphores and we optimistically begin by working on the blocked threads { + // We need to re-think this with SMR ThreadsList. + // There is assumption in code that Threads_lock should be lock + // during certain phases. MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { ! // A new thread on the ThreadsList will not have an operation. ! // Hence is skipped in handshake_process_by_vmthread. thr->handshake_process_by_vmthread(); } } while (poll_for_completed_thread()) { + // Includes canceled operations by exiting threads. number_of_threads_completed++; } } while (number_of_threads_issued != number_of_threads_completed); }
*** 210,220 **** _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {} VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {} void doit() { ! ALL_JAVA_THREADS(t) { if (_all_threads || t == _target_thread) { if (t == _target_thread) { _thread_alive = true; } _thread_cl->do_thread(t); --- 228,238 ---- _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {} VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {} void doit() { ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { if (_all_threads || t == _target_thread) { if (t == _target_thread) { _thread_alive = true; } _thread_cl->do_thread(t);
*** 296,307 **** void HandshakeState::cancel_inner(JavaThread* thread) { assert(Thread::current() == thread, "should call from thread"); assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); #ifdef DEBUG { ! MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); ! assert(!Threads::includes(thread), "java thread must not be on threads list"); } #endif HandshakeOperation* op = _operation; clear_handshake(thread); if (op != NULL) { --- 314,325 ---- void HandshakeState::cancel_inner(JavaThread* thread) { assert(Thread::current() == thread, "should call from thread"); assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); #ifdef DEBUG { ! ThreadsListHandle tlh; ! assert(!tlh.includes(_target), "java thread must not be on threads list"); } #endif HandshakeOperation* op = _operation; clear_handshake(thread); if (op != NULL) {
< prev index next >