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