< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 57126 : [mq]: 8234796-v2
rev 57127 : imported patch 8234742-v2
rev 57128 : [mq]: 8234742-v3


  34 #include "runtime/task.hpp"
  35 #include "runtime/thread.hpp"
  36 #include "runtime/vmThread.hpp"
  37 #include "utilities/formatBuffer.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 class HandshakeOperation: public StackObj {
  41 public:
  42   virtual void do_handshake(JavaThread* thread) = 0;
  43 };
  44 
  45 class HandshakeThreadsOperation: public HandshakeOperation {
  46   static Semaphore _done;
  47   HandshakeClosure* _handshake_cl;
  48   bool _executed;
  49 public:
  50   HandshakeThreadsOperation(HandshakeClosure* cl) : _handshake_cl(cl), _executed(false) {}
  51   void do_handshake(JavaThread* thread);
  52   bool thread_has_completed() { return _done.trywait(); }
  53   bool executed() const { return _executed; }

  54 
  55 #ifdef ASSERT
  56   void check_state() {
  57     assert(!_done.trywait(), "Must be zero");
  58   }
  59 #endif
  60 };
  61 
  62 Semaphore HandshakeThreadsOperation::_done(0);
  63 
  64 class VM_Handshake: public VM_Operation {
  65   const jlong _handshake_timeout;
  66  public:
  67   bool evaluate_at_safepoint() const { return false; }
  68 
  69   bool evaluate_concurrently() const { return false; }
  70 
  71  protected:
  72   HandshakeThreadsOperation* const _op;
  73 


  90 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  91   // Check if handshake operation has timed out
  92   if (_handshake_timeout > 0) {
  93     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  94   }
  95   return false;
  96 }
  97 
  98 void VM_Handshake::handle_timeout() {
  99   LogStreamHandle(Warning, handshake) log_stream;
 100   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
 101     if (thr->has_handshake()) {
 102       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
 103       thr->print_thread_state_on(&log_stream);
 104     }
 105   }
 106   log_stream.flush();
 107   fatal("Handshake operation timed out");
 108 }
 109 
 110 static void log_handshake_info(jlong start_time_ns, const char* name, int targets, int vmt_executed, const char* extra) {
 111   if (start_time_ns != 0) {
 112     jlong completion_time = os::javaTimeNanos() - start_time_ns;
 113     log_info(handshake)("Handshake \"%s\", Targeted threads: %d, Executed by targeted threads: %d, Total completion time: " JLONG_FORMAT " ns%s",
 114                         name, targets, targets - vmt_executed, completion_time, extra);




 115   }
 116 }
 117 
 118 class VM_HandshakeOneThread: public VM_Handshake {
 119   JavaThread* _target;
 120  public:
 121   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 122     VM_Handshake(op), _target(target) {}
 123 
 124   void doit() {
 125     DEBUG_ONLY(_op->check_state();)
 126 
 127     jlong start_time_ns = 0;
 128     if (log_is_enabled(Info, handshake)) {
 129       start_time_ns = os::javaTimeNanos();
 130     }
 131 
 132     ThreadsListHandle tlh;
 133     if (tlh.includes(_target)) {
 134       set_handshake(_target);
 135     } else {
 136       log_handshake_info(start_time_ns, _op->name(), 0, 0, " (thread dead)");
 137       return;
 138     }
 139 
 140     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
 141     jlong timeout_start_time = os::elapsed_counter();
 142     bool by_vm_thread = false;
 143     do {
 144       if (handshake_has_timed_out(timeout_start_time)) {
 145         handle_timeout();
 146       }
 147 
 148       // We need to re-think this with SMR ThreadsList.
 149       // There is an assumption in the code that the Threads_lock should be
 150       // locked during certain phases.
 151       {
 152         MutexLocker ml(Threads_lock);
 153         by_vm_thread = _target->handshake_process_by_vmthread();
 154       }
 155     } while (!poll_for_completed_thread());
 156     DEBUG_ONLY(_op->check_state();)
 157     log_handshake_info(start_time_ns, _op->name(), 1, by_vm_thread ? 1 : 0, "");
 158   }
 159 
 160   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 161 
 162   bool executed() const { return _op->executed(); }
 163 };
 164 
 165 class VM_HandshakeAllThreads: public VM_Handshake {
 166  public:
 167   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 168 
 169   void doit() {
 170     DEBUG_ONLY(_op->check_state();)
 171 
 172     jlong start_time_ns = 0;
 173     if (log_is_enabled(Info, handshake)) {
 174       start_time_ns = os::javaTimeNanos();
 175     }
 176     int handshake_executed_by_vm_thread = 0;
 177 
 178     JavaThreadIteratorWithHandle jtiwh;
 179     int number_of_threads_issued = 0;
 180     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 181       set_handshake(thr);
 182       number_of_threads_issued++;
 183     }
 184 
 185     if (number_of_threads_issued < 1) {
 186       log_handshake_info(start_time_ns, _op->name(), 0, 0, " (no threads)");
 187       return;
 188     }
 189 
 190     log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 191     const jlong start_time = os::elapsed_counter();
 192     int number_of_threads_completed = 0;
 193     do {
 194       // Check if handshake operation has timed out
 195       if (handshake_has_timed_out(start_time)) {
 196         handle_timeout();
 197       }
 198 
 199       // Have VM thread perform the handshake operation for blocked threads.
 200       // Observing a blocked state may of course be transient but the processing is guarded
 201       // by semaphores and we optimistically begin by working on the blocked threads
 202       {
 203           // We need to re-think this with SMR ThreadsList.
 204           // There is an assumption in the code that the Threads_lock should
 205           // be locked during certain phases.
 206           jtiwh.rewind();
 207           MutexLocker ml(Threads_lock);
 208           for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 209             // A new thread on the ThreadsList will not have an operation,
 210             // hence it is skipped in handshake_process_by_vmthread.
 211             if (thr->handshake_process_by_vmthread()) {
 212               handshake_executed_by_vm_thread++;
 213             }
 214           }
 215       }
 216 
 217       while (poll_for_completed_thread()) {
 218         // Includes canceled operations by exiting threads.
 219         number_of_threads_completed++;
 220       }
 221 
 222     } while (number_of_threads_issued > number_of_threads_completed);
 223     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 224     DEBUG_ONLY(_op->check_state();)
 225 
 226     log_handshake_info(start_time_ns, _op->name(), number_of_threads_issued, handshake_executed_by_vm_thread, "");
 227   }
 228 
 229   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 230 };
 231 
 232 class VM_HandshakeFallbackOperation : public VM_Operation {
 233   HandshakeClosure* _handshake_cl;
 234   Thread* _target_thread;
 235   bool _all_threads;
 236   bool _executed;
 237 public:
 238   VM_HandshakeFallbackOperation(HandshakeClosure* cl) :
 239       _handshake_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
 240   VM_HandshakeFallbackOperation(HandshakeClosure* cl, Thread* target) :
 241       _handshake_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
 242 
 243   void doit() {
 244     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation, operation: %s", name());
 245     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 246       if (_all_threads || t == _target_thread) {


 361 
 362   case _thread_blocked:
 363     return true;
 364 
 365   default:
 366     return false;
 367   }
 368 }
 369 
 370 bool HandshakeState::claim_handshake_for_vmthread() {
 371   if (!_semaphore.trywait()) {
 372     return false;
 373   }
 374   if (has_operation()) {
 375     return true;
 376   }
 377   _semaphore.signal();
 378   return false;
 379 }
 380 
 381 bool HandshakeState::process_by_vmthread(JavaThread* target) {
 382   assert(Thread::current()->is_VM_thread(), "should call from vm thread");
 383   // Threads_lock must be held here, but that is assert()ed in
 384   // possibly_vmthread_can_process_handshake().
 385 
 386   if (!has_operation()) {
 387     // JT has already cleared its handshake
 388     return false;
 389   }
 390 
 391   if (!possibly_vmthread_can_process_handshake(target)) {
 392     // JT is observed in an unsafe state, it must notice the handshake itself
 393     return false;
 394   }
 395 
 396   // Claim the semaphore if there still an operation to be executed.
 397   if (!claim_handshake_for_vmthread()) {
 398     return false;
 399   }
 400 
 401   // If we own the semaphore at this point and while owning the semaphore


  34 #include "runtime/task.hpp"
  35 #include "runtime/thread.hpp"
  36 #include "runtime/vmThread.hpp"
  37 #include "utilities/formatBuffer.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 class HandshakeOperation: public StackObj {
  41 public:
  42   virtual void do_handshake(JavaThread* thread) = 0;
  43 };
  44 
  45 class HandshakeThreadsOperation: public HandshakeOperation {
  46   static Semaphore _done;
  47   HandshakeClosure* _handshake_cl;
  48   bool _executed;
  49 public:
  50   HandshakeThreadsOperation(HandshakeClosure* cl) : _handshake_cl(cl), _executed(false) {}
  51   void do_handshake(JavaThread* thread);
  52   bool thread_has_completed() { return _done.trywait(); }
  53   bool executed() const { return _executed; }
  54   const char* name() { return _handshake_cl->name(); }
  55 
  56 #ifdef ASSERT
  57   void check_state() {
  58     assert(!_done.trywait(), "Must be zero");
  59   }
  60 #endif
  61 };
  62 
  63 Semaphore HandshakeThreadsOperation::_done(0);
  64 
  65 class VM_Handshake: public VM_Operation {
  66   const jlong _handshake_timeout;
  67  public:
  68   bool evaluate_at_safepoint() const { return false; }
  69 
  70   bool evaluate_concurrently() const { return false; }
  71 
  72  protected:
  73   HandshakeThreadsOperation* const _op;
  74 


  91 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  92   // Check if handshake operation has timed out
  93   if (_handshake_timeout > 0) {
  94     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  95   }
  96   return false;
  97 }
  98 
  99 void VM_Handshake::handle_timeout() {
 100   LogStreamHandle(Warning, handshake) log_stream;
 101   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
 102     if (thr->has_handshake()) {
 103       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
 104       thr->print_thread_state_on(&log_stream);
 105     }
 106   }
 107   log_stream.flush();
 108   fatal("Handshake operation timed out");
 109 }
 110 
 111 static void log_handshake_info(jlong start_time_ns, const char* name, int targets, int vmt_executed, const char* extra = NULL) {
 112   if (start_time_ns != 0) {
 113     jlong completion_time = os::javaTimeNanos() - start_time_ns;
 114     log_info(handshake)("Handshake \"%s\", Targeted threads: %d, Executed by targeted threads: %d, Total completion time: " JLONG_FORMAT " ns%s%s",
 115                         name, targets,
 116                         targets - vmt_executed,
 117                         completion_time,
 118                         extra != NULL ? ", " : "",
 119                         extra != NULL ? extra : "");
 120   }
 121 }
 122 
 123 class VM_HandshakeOneThread: public VM_Handshake {
 124   JavaThread* _target;
 125  public:
 126   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 127     VM_Handshake(op), _target(target) {}
 128 
 129   void doit() {
 130     DEBUG_ONLY(_op->check_state();)
 131 
 132     jlong start_time_ns = 0;
 133     if (log_is_enabled(Info, handshake)) {
 134       start_time_ns = os::javaTimeNanos();
 135     }
 136 
 137     ThreadsListHandle tlh;
 138     if (tlh.includes(_target)) {
 139       set_handshake(_target);
 140     } else {
 141       log_handshake_info(start_time_ns, _op->name(), 0, 0, "(thread dead)");
 142       return;
 143     }
 144 
 145     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
 146     jlong timeout_start_time = os::elapsed_counter();
 147     bool by_vm_thread = false;
 148     do {
 149       if (handshake_has_timed_out(timeout_start_time)) {
 150         handle_timeout();
 151       }
 152 
 153       // We need to re-think this with SMR ThreadsList.
 154       // There is an assumption in the code that the Threads_lock should be
 155       // locked during certain phases.
 156       {
 157         MutexLocker ml(Threads_lock);
 158         by_vm_thread = _target->handshake_try_process_by_vmThread();
 159       }
 160     } while (!poll_for_completed_thread());
 161     DEBUG_ONLY(_op->check_state();)
 162     log_handshake_info(start_time_ns, _op->name(), 1, by_vm_thread ? 1 : 0);
 163   }
 164 
 165   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 166 
 167   bool executed() const { return _op->executed(); }
 168 };
 169 
 170 class VM_HandshakeAllThreads: public VM_Handshake {
 171  public:
 172   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 173 
 174   void doit() {
 175     DEBUG_ONLY(_op->check_state();)
 176 
 177     jlong start_time_ns = 0;
 178     if (log_is_enabled(Info, handshake)) {
 179       start_time_ns = os::javaTimeNanos();
 180     }
 181     int handshake_executed_by_vm_thread = 0;
 182 
 183     JavaThreadIteratorWithHandle jtiwh;
 184     int number_of_threads_issued = 0;
 185     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 186       set_handshake(thr);
 187       number_of_threads_issued++;
 188     }
 189 
 190     if (number_of_threads_issued < 1) {
 191       log_handshake_info(start_time_ns, _op->name(), 0, 0);
 192       return;
 193     }
 194 
 195     log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThread");
 196     const jlong start_time = os::elapsed_counter();
 197     int number_of_threads_completed = 0;
 198     do {
 199       // Check if handshake operation has timed out
 200       if (handshake_has_timed_out(start_time)) {
 201         handle_timeout();
 202       }
 203 
 204       // Have VM thread perform the handshake operation for blocked threads.
 205       // Observing a blocked state may of course be transient but the processing is guarded
 206       // by semaphores and we optimistically begin by working on the blocked threads
 207       {
 208           // We need to re-think this with SMR ThreadsList.
 209           // There is an assumption in the code that the Threads_lock should
 210           // be locked during certain phases.
 211           jtiwh.rewind();
 212           MutexLocker ml(Threads_lock);
 213           for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 214             // A new thread on the ThreadsList will not have an operation,
 215             // hence it is skipped in handshake_process_by_vmthread.
 216             if (thr->handshake_try_process_by_vmThread()) {
 217               handshake_executed_by_vm_thread++;
 218             }
 219           }
 220       }
 221 
 222       while (poll_for_completed_thread()) {
 223         // Includes canceled operations by exiting threads.
 224         number_of_threads_completed++;
 225       }
 226 
 227     } while (number_of_threads_issued > number_of_threads_completed);
 228     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 229     DEBUG_ONLY(_op->check_state();)
 230 
 231     log_handshake_info(start_time_ns, _op->name(), number_of_threads_issued, handshake_executed_by_vm_thread);
 232   }
 233 
 234   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 235 };
 236 
 237 class VM_HandshakeFallbackOperation : public VM_Operation {
 238   HandshakeClosure* _handshake_cl;
 239   Thread* _target_thread;
 240   bool _all_threads;
 241   bool _executed;
 242 public:
 243   VM_HandshakeFallbackOperation(HandshakeClosure* cl) :
 244       _handshake_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
 245   VM_HandshakeFallbackOperation(HandshakeClosure* cl, Thread* target) :
 246       _handshake_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
 247 
 248   void doit() {
 249     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation, operation: %s", name());
 250     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 251       if (_all_threads || t == _target_thread) {


 366 
 367   case _thread_blocked:
 368     return true;
 369 
 370   default:
 371     return false;
 372   }
 373 }
 374 
 375 bool HandshakeState::claim_handshake_for_vmthread() {
 376   if (!_semaphore.trywait()) {
 377     return false;
 378   }
 379   if (has_operation()) {
 380     return true;
 381   }
 382   _semaphore.signal();
 383   return false;
 384 }
 385 
 386 bool HandshakeState::try_process_by_vmThread(JavaThread* target) {
 387   assert(Thread::current()->is_VM_thread(), "should call from vm thread");
 388   // Threads_lock must be held here, but that is assert()ed in
 389   // possibly_vmthread_can_process_handshake().
 390 
 391   if (!has_operation()) {
 392     // JT has already cleared its handshake
 393     return false;
 394   }
 395 
 396   if (!possibly_vmthread_can_process_handshake(target)) {
 397     // JT is observed in an unsafe state, it must notice the handshake itself
 398     return false;
 399   }
 400 
 401   // Claim the semaphore if there still an operation to be executed.
 402   if (!claim_handshake_for_vmthread()) {
 403     return false;
 404   }
 405 
 406   // If we own the semaphore at this point and while owning the semaphore
< prev index next >