< 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 >