< prev index next >
src/hotspot/share/runtime/handshake.cpp
Print this page
@@ -43,20 +43,20 @@
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(); }
- void set_isdirect() { _is_direct = true; }
bool is_direct() { return _is_direct; }
#ifdef ASSERT
void check_state() {
assert(_pending_threads == 0, "Must be zero");
@@ -252,64 +252,62 @@
// It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation
}
void Handshake::execute(HandshakeClosure* thread_cl) {
if (SafepointMechanism::uses_thread_local_poll()) {
- HandshakeOperation cto(thread_cl);
- VM_HandshakeAllThreads handshake(&cto);
+ HandshakeOperation ho(thread_cl);
+ VM_HandshakeAllThreads handshake(&ho);
VMThread::execute(&handshake);
} else {
VM_HandshakeFallbackOperation op(thread_cl);
VMThread::execute(&op);
}
}
-bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target, bool is_direct_handshake) {
+bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) {
if (SafepointMechanism::uses_thread_local_poll()) {
HandshakeOperation ho(thread_cl);
- if (is_direct_handshake) {
- direct_handshake(target, &ho);
- } else {
- VM_HandshakeOneThread op(&ho, target);
- VMThread::execute(&op);
- }
- return ho.executed();
+ VM_HandshakeOneThread handshake(&ho, target);
+ VMThread::execute(&handshake);
+ return handshake.executed();
} else {
VM_HandshakeFallbackOperation op(thread_cl, target);
VMThread::execute(&op);
return op.executed();
}
}
-void Handshake::direct_handshake(JavaThread* target, HandshakeOperation *op) {
+bool Handshake::execute_direct(HandshakeClosure* thread_cl, JavaThread* target) {
JavaThread *self = (JavaThread*)Thread::current();
- op->set_isdirect();
+ HandshakeOperation op(thread_cl, true);
jlong start_time_ns = 0;
if (log_is_enabled(Info, handshake)) {
start_time_ns = os::javaTimeNanos();
}
ThreadsListHandle tlh;
if (tlh.includes(target)) {
- target->set_handshake_operation(op);
+ target->set_handshake_operation(&op);
} else {
- log_handshake_info(start_time_ns, op->name(), 0, 0, "(thread dead)");
- return;
+ log_handshake_info(start_time_ns, op.name(), 0, 0, "(thread dead)");
+ return false;
}
bool by_handshaker = false;
- while (!op->is_completed()) {
- by_handshaker = target->handshake_try_process(op);
+ while (!op.is_completed()) {
+ by_handshaker = target->handshake_try_process(&op);
// Check for pending handshakes to avoid possible deadlocks where our
// target is trying to handshake us.
if (SafepointMechanism::should_block(self)) {
ThreadBlockInVM tbivm(self);
}
}
- DEBUG_ONLY(op->check_state();)
- log_handshake_info(start_time_ns, op->name(), 1, by_handshaker ? 1 : 0);
+ DEBUG_ONLY(op.check_state();)
+ 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;)
}
@@ -343,23 +341,26 @@
do {
ThreadInVMForHandshake tivm(_thread);
if (!_processing_sem.trywait()) {
_processing_sem.wait_with_safepoint_check(_thread);
}
- bool is_direct_handshake = false;
- HandshakeOperation* op = Atomic::load_acquire(&_operation);
- if (op == NULL) {
- op = Atomic::load_acquire(&_operation_direct);
- is_direct_handshake = true;
- }
- if (op != NULL) {
+ 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(is_direct_handshake);
+ clear_handshake(true);
op->do_handshake(_thread);
}
+ }
_processing_sem.signal();
} while (has_operation());
}
bool HandshakeState::can_process_handshake() {
@@ -391,21 +392,21 @@
bool HandshakeState::claim_handshake(bool is_direct) {
if (!_processing_sem.trywait()) {
return false;
}
- if ((!is_direct && _operation != NULL) || (is_direct && _operation_direct != NULL)){
+ if (has_specific_operation(is_direct)){
return true;
}
_processing_sem.signal();
return false;
}
bool HandshakeState::try_process(HandshakeOperation* op) {
bool is_direct = op->is_direct();
- if ((!is_direct && _operation == NULL) || (is_direct && _operation_direct == NULL)){
+ if (!has_specific_operation(is_direct)){
// JT has already cleared its handshake
return false;
}
if (!possibly_can_process_handshake()) {
< prev index next >