< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 47863 : imported patch 10.08.open.rebase_20171114.rehn
rev 47865 : dholmes CR: Fix indents, trailing spaces and various typos. Add descriptions for the '_cnt', '_max' and '_times" fields, add impl notes to document the type choices.

*** 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,149 **** do { if (handshake_has_timed_out(start_time)) { handle_timeout(); } MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); _target->handshake_process_by_vmthread(); ! } while (!poll_for_completed_thread()); } VMOp_Type type() const { return VMOp_HandshakeOneThread; } --- 134,161 ---- do { if (handshake_has_timed_out(start_time)) { handle_timeout(); } + // We need to re-think this with SMR ThreadsList. + // There is an assumption in the code that the Threads_lock should be + // locked during certain phases. MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); + ThreadsListHandle tlh; + if (tlh.includes(_target)) { + // Warning _target's 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 + // _target's address should be okay since the new thread will not have + // an operation. _target->handshake_process_by_vmthread(); ! } else { ! // We can't warn here since the thread does cancel_handshake after ! // it has been removed from the ThreadsList. So we should just keep ! // looping here until while below returns false. If we have a bug, ! // then we hang 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(); } --- 167,194 ---- 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); } --- 195,217 ---- // 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 an assumption in the code that the Threads_lock should + // be locked 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 it 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); --- 229,239 ---- _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) { --- 315,326 ---- 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 >