< prev index next >
src/hotspot/share/runtime/handshake.cpp
Print this page
@@ -51,22 +51,22 @@
_is_direct(is_direct) {}
void do_handshake(JavaThread* thread);
bool is_completed() {
int32_t val = Atomic::load(&_pending_threads);
- assert(val >= 0, "_pending_threads cannot be negative");
+ assert(val >= 0, "_pending_threads=%d cannot be negative", val);
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(); }
bool is_direct() { return _is_direct; }
#ifdef ASSERT
void check_state() {
- assert(_pending_threads == 0, "Must be zero");
+ assert(_pending_threads == 0, "Must be zero: %d", _pending_threads);
}
#endif
};
class VM_Handshake: public VM_Operation {
@@ -223,11 +223,16 @@
jlong completion_time = os::javaTimeNanos() - start_time_ns;
log_debug(handshake, task)("Operation: %s for thread " PTR_FORMAT ", is_vm_thread: %s, completed in " JLONG_FORMAT " ns",
name(), p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()), completion_time);
}
- // Inform VMThread/Handshaker that we have completed the operation
+ // Inform VMThread/Handshaker that we have completed the operation.
+ // When this is executed by the Handshakee we need a release store
+ // here to make sure memory operations executed in the handshake
+ // closure are visible to the Handshaker after it reads that the
+ // operation has completed. Atomic::dec() already provides a full
+ // memory fence.
Atomic::dec(&_pending_threads);
// It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation
}
@@ -271,10 +276,15 @@
}
}
DEBUG_ONLY(op.check_state();)
log_handshake_info(start_time_ns, op.name(), 1, by_handshaker ? 1 : 0);
+ // Prevent future loads from floating above the load of _pending_threads
+ // in is_completed(). This prevents reading stale data modified in the
+ // handshake closure by the Handshakee.
+ OrderAccess::acquire();
+
return op.executed();
}
HandshakeState::HandshakeState() :
_operation(NULL),
@@ -397,11 +407,11 @@
}
// Check if the handshake operation is the same as the one we meant to execute. The
// handshake could have been already processed by the handshakee and a new handshake
// by another JavaThread might be in progress.
- if ( (is_direct && op != _operation_direct)) {
+ if (is_direct && op != _operation_direct) {
_processing_sem.signal();
return false;
}
// If we own the semaphore at this point and while owning the semaphore
< prev index next >