< 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,12 +35,10 @@
#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;
};
@@ -92,12 +90,11 @@
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) {
+ 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,12 +112,12 @@
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)) {
+ ThreadsListHandle tlh;
+ if (tlh.includes(_target)) {
set_handshake(_target);
_thread_alive = true;
}
}
@@ -137,13 +134,28 @@
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,27 +167,28 @@
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) {
+ 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,17 +195,23 @@
// 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);
- ALL_JAVA_THREADS(thr) {
+ 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,11 +229,11 @@
_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) {
+ 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,12 +315,12 @@
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");
+ 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 >