< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 47863 : imported patch 10.08.open.rebase_20171114.rehn
rev 47865 : dholmes CR: Fix indents, trailing spaces and various typos. Add descriptions for the '_cnt', '_max' and '_times" fields, add impl notes to document the type choices.


  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "logging/log.hpp"
  27 #include "logging/logStream.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "runtime/handshake.hpp"
  30 #include "runtime/interfaceSupport.hpp"
  31 #include "runtime/osThread.hpp"
  32 #include "runtime/semaphore.hpp"
  33 #include "runtime/task.hpp"
  34 #include "runtime/timerTrace.hpp"
  35 #include "runtime/thread.hpp"
  36 #include "runtime/vmThread.hpp"
  37 #include "utilities/formatBuffer.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 #define ALL_JAVA_THREADS(X) for (JavaThread* X = Threads::first(); X; X = X->next())
  41 
  42 class HandshakeOperation: public StackObj {
  43 public:
  44   virtual void do_handshake(JavaThread* thread) = 0;
  45   virtual void cancel_handshake(JavaThread* thread) = 0;
  46 };
  47 
  48 class HandshakeThreadsOperation: public HandshakeOperation {
  49   Semaphore _done;
  50   ThreadClosure* _thread_cl;
  51 
  52 public:
  53   HandshakeThreadsOperation(ThreadClosure* cl) : _done(0), _thread_cl(cl) {}
  54   void do_handshake(JavaThread* thread);
  55   void cancel_handshake(JavaThread* thread) { _done.signal(); };
  56 
  57   bool thread_has_completed() { return _done.trywait(); }
  58 };
  59 
  60 class VM_Handshake: public VM_Operation {
  61   HandshakeThreadsOperation* const _op;


  77 
  78   // This method returns true for threads completed their operation
  79   // and true for threads canceled their operation.
  80   // A cancellation can happen if the thread is exiting.
  81   bool poll_for_completed_thread() { return _op->thread_has_completed(); }
  82 
  83   bool handshake_has_timed_out(jlong start_time);
  84   static void handle_timeout();
  85 };
  86 
  87 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  88   // Check if handshake operation has timed out
  89   if (_handshake_timeout > 0) {
  90     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  91   }
  92   return false;
  93 }
  94 
  95 void VM_Handshake::handle_timeout() {
  96   LogStreamHandle(Warning, handshake) log_stream;
  97   MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
  98   ALL_JAVA_THREADS(thr) {
  99     if (thr->has_handshake()) {
 100       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
 101       thr->print_thread_state_on(&log_stream);
 102     }
 103   }
 104   log_stream.flush();
 105   fatal("Handshake operation timed out");
 106 }
 107 
 108 
 109 class VM_HandshakeOneThread: public VM_Handshake {
 110   JavaThread* _target;
 111   bool _thread_alive;
 112  public:
 113   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 114     VM_Handshake(op), _target(target), _thread_alive(false) {}
 115 
 116   void doit() {
 117     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 118 
 119     {
 120       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 121       if (Threads::includes(_target)) {
 122         set_handshake(_target);
 123         _thread_alive = true;
 124       }
 125     }
 126 
 127     if (!_thread_alive) {
 128       return;
 129     }
 130 
 131     if (!UseMembar) {
 132       os::serialize_thread_states();
 133     }
 134 
 135     log_trace(handshake)("Thread signaled, begin processing by VMThtread");
 136     jlong start_time = os::elapsed_counter();
 137     do {
 138       if (handshake_has_timed_out(start_time)) {
 139         handle_timeout();
 140       }
 141 



 142       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);







 143       _target->handshake_process_by_vmthread();
 144 





 145     } while (!poll_for_completed_thread());
 146   }
 147 
 148   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 149 
 150   bool thread_alive() const { return _thread_alive; }
 151 };
 152 
 153 class VM_HandshakeAllThreads: public VM_Handshake {
 154  public:
 155   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 156 
 157   void doit() {
 158     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 159 
 160     int number_of_threads_issued = -1;
 161     int number_of_threads_completed = 0;
 162     {
 163       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 164       number_of_threads_issued = Threads::number_of_threads();
 165 
 166       ALL_JAVA_THREADS(thr) {
 167         set_handshake(thr);

 168       }




 169     }
 170 
 171     if (!UseMembar) {
 172       os::serialize_thread_states();
 173     }
 174 
 175     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 176     const jlong start_time = os::elapsed_counter();

 177     do {
 178       // Check if handshake operation has timed out
 179       if (handshake_has_timed_out(start_time)) {
 180         handle_timeout();
 181       }
 182 
 183       // Have VM thread perform the handshake operation for blocked threads.
 184       // Observing a blocked state may of course be transient but the processing is guarded
 185       // by semaphores and we optimistically begin by working on the blocked threads
 186       {



 187           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 188           ALL_JAVA_THREADS(thr) {


 189             thr->handshake_process_by_vmthread();
 190           }
 191       }
 192 
 193       while (poll_for_completed_thread()) {

 194         number_of_threads_completed++;
 195       }
 196 
 197     } while (number_of_threads_issued != number_of_threads_completed);
 198   }
 199 
 200   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 201 };
 202 
 203 class VM_HandshakeFallbackOperation : public VM_Operation {
 204   ThreadClosure* _thread_cl;
 205   Thread* _target_thread;
 206   bool _all_threads;
 207   bool _thread_alive;
 208 public:
 209   VM_HandshakeFallbackOperation(ThreadClosure* cl) :
 210       _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
 211   VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
 212       _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
 213 
 214   void doit() {
 215     ALL_JAVA_THREADS(t) {
 216       if (_all_threads || t == _target_thread) {
 217         if (t == _target_thread) {
 218           _thread_alive = true;
 219         }
 220         _thread_cl->do_thread(t);
 221       }
 222     }
 223   }
 224 
 225   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 226   bool thread_alive() const { return _thread_alive; }
 227 };
 228 
 229 #undef ALL_JAVA_THREADS
 230 
 231 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
 232   ResourceMark rm;
 233   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 234                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 235   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));


 281   ThreadInVMForHandshake tivm(thread);
 282   if (!_semaphore.trywait()) {
 283     ThreadBlockInVM tbivm(thread);
 284     _semaphore.wait();
 285   }
 286   if (has_operation()) {
 287     HandshakeOperation* op = _operation;
 288     clear_handshake(thread);
 289     if (op != NULL) {
 290       op->do_handshake(thread);
 291     }
 292   }
 293   _semaphore.signal();
 294 }
 295 
 296 void HandshakeState::cancel_inner(JavaThread* thread) {
 297   assert(Thread::current() == thread, "should call from thread");
 298   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
 299 #ifdef DEBUG
 300   {
 301     MutexLockerEx ml(Threads_lock,  Mutex::_no_safepoint_check_flag);
 302     assert(!Threads::includes(thread), "java thread must not be on threads list");
 303   }
 304 #endif
 305   HandshakeOperation* op = _operation;
 306   clear_handshake(thread);
 307   if (op != NULL) {
 308     op->cancel_handshake(thread);
 309   }
 310 }
 311 
 312 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
 313   return SafepointSynchronize::safepoint_safe(target, target->thread_state());
 314 }
 315 
 316 bool HandshakeState::claim_handshake_for_vmthread() {
 317   if (_semaphore.trywait()) {
 318     if (has_operation()) {
 319       _vmthread_holds_semaphore = true;
 320     } else {
 321       _semaphore.signal();
 322     }




  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "logging/log.hpp"
  27 #include "logging/logStream.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "runtime/handshake.hpp"
  30 #include "runtime/interfaceSupport.hpp"
  31 #include "runtime/osThread.hpp"
  32 #include "runtime/semaphore.hpp"
  33 #include "runtime/task.hpp"
  34 #include "runtime/timerTrace.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   virtual void cancel_handshake(JavaThread* thread) = 0;
  44 };
  45 
  46 class HandshakeThreadsOperation: public HandshakeOperation {
  47   Semaphore _done;
  48   ThreadClosure* _thread_cl;
  49 
  50 public:
  51   HandshakeThreadsOperation(ThreadClosure* cl) : _done(0), _thread_cl(cl) {}
  52   void do_handshake(JavaThread* thread);
  53   void cancel_handshake(JavaThread* thread) { _done.signal(); };
  54 
  55   bool thread_has_completed() { return _done.trywait(); }
  56 };
  57 
  58 class VM_Handshake: public VM_Operation {
  59   HandshakeThreadsOperation* const _op;


  75 
  76   // This method returns true for threads completed their operation
  77   // and true for threads canceled their operation.
  78   // A cancellation can happen if the thread is exiting.
  79   bool poll_for_completed_thread() { return _op->thread_has_completed(); }
  80 
  81   bool handshake_has_timed_out(jlong start_time);
  82   static void handle_timeout();
  83 };
  84 
  85 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  86   // Check if handshake operation has timed out
  87   if (_handshake_timeout > 0) {
  88     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  89   }
  90   return false;
  91 }
  92 
  93 void VM_Handshake::handle_timeout() {
  94   LogStreamHandle(Warning, handshake) log_stream;
  95   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {

  96     if (thr->has_handshake()) {
  97       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
  98       thr->print_thread_state_on(&log_stream);
  99     }
 100   }
 101   log_stream.flush();
 102   fatal("Handshake operation timed out");
 103 }
 104 
 105 
 106 class VM_HandshakeOneThread: public VM_Handshake {
 107   JavaThread* _target;
 108   bool _thread_alive;
 109  public:
 110   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 111     VM_Handshake(op), _target(target), _thread_alive(false) {}
 112 
 113   void doit() {
 114     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 115 
 116     {
 117       ThreadsListHandle tlh;
 118       if (tlh.includes(_target)) {
 119         set_handshake(_target);
 120         _thread_alive = true;
 121       }
 122     }
 123 
 124     if (!_thread_alive) {
 125       return;
 126     }
 127 
 128     if (!UseMembar) {
 129       os::serialize_thread_states();
 130     }
 131 
 132     log_trace(handshake)("Thread signaled, begin processing by VMThtread");
 133     jlong start_time = os::elapsed_counter();
 134     do {
 135       if (handshake_has_timed_out(start_time)) {
 136         handle_timeout();
 137       }
 138 
 139       // We need to re-think this with SMR ThreadsList.
 140       // There is an assumption in the code that the Threads_lock should be
 141       // locked during certain phases.
 142       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 143       ThreadsListHandle tlh;
 144       if (tlh.includes(_target)) {
 145         // Warning _target's address might be re-used.
 146         // handshake_process_by_vmthread will check the semaphore for us again.
 147         // Since we can't have more then one handshake in flight a reuse of
 148         // _target's address should be okay since the new thread will not have
 149         // an operation.
 150         _target->handshake_process_by_vmthread();
 151       } else {
 152         // We can't warn here since the thread does cancel_handshake after
 153         // it has been removed from the ThreadsList. So we should just keep
 154         // looping here until while below returns false. If we have a bug,
 155         // then we hang here, which is good for debugging.
 156       }
 157     } while (!poll_for_completed_thread());
 158   }
 159 
 160   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 161 
 162   bool thread_alive() const { return _thread_alive; }
 163 };
 164 
 165 class VM_HandshakeAllThreads: public VM_Handshake {
 166  public:
 167   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 168 
 169   void doit() {
 170     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 171 
 172     int number_of_threads_issued = 0;
 173     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {





 174       set_handshake(thr);
 175       number_of_threads_issued++;
 176     }
 177 
 178     if (number_of_threads_issued < 1) {
 179       log_debug(handshake)("No threads to handshake.");
 180       return;
 181     }
 182 
 183     if (!UseMembar) {
 184       os::serialize_thread_states();
 185     }
 186 
 187     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 188     const jlong start_time = os::elapsed_counter();
 189     int number_of_threads_completed = 0;
 190     do {
 191       // Check if handshake operation has timed out
 192       if (handshake_has_timed_out(start_time)) {
 193         handle_timeout();
 194       }
 195 
 196       // Have VM thread perform the handshake operation for blocked threads.
 197       // Observing a blocked state may of course be transient but the processing is guarded
 198       // by semaphores and we optimistically begin by working on the blocked threads
 199       {
 200           // We need to re-think this with SMR ThreadsList.
 201           // There is an assumption in the code that the Threads_lock should
 202           // be locked during certain phases.
 203           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 204           for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
 205             // A new thread on the ThreadsList will not have an operation,
 206             // hence it is skipped in handshake_process_by_vmthread.
 207             thr->handshake_process_by_vmthread();
 208           }
 209       }
 210 
 211       while (poll_for_completed_thread()) {
 212         // Includes canceled operations by exiting threads.
 213         number_of_threads_completed++;
 214       }
 215 
 216     } while (number_of_threads_issued != number_of_threads_completed);
 217   }
 218 
 219   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 220 };
 221 
 222 class VM_HandshakeFallbackOperation : public VM_Operation {
 223   ThreadClosure* _thread_cl;
 224   Thread* _target_thread;
 225   bool _all_threads;
 226   bool _thread_alive;
 227 public:
 228   VM_HandshakeFallbackOperation(ThreadClosure* cl) :
 229       _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
 230   VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
 231       _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
 232 
 233   void doit() {
 234     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 235       if (_all_threads || t == _target_thread) {
 236         if (t == _target_thread) {
 237           _thread_alive = true;
 238         }
 239         _thread_cl->do_thread(t);
 240       }
 241     }
 242   }
 243 
 244   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 245   bool thread_alive() const { return _thread_alive; }
 246 };
 247 
 248 #undef ALL_JAVA_THREADS
 249 
 250 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
 251   ResourceMark rm;
 252   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 253                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 254   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));


 300   ThreadInVMForHandshake tivm(thread);
 301   if (!_semaphore.trywait()) {
 302     ThreadBlockInVM tbivm(thread);
 303     _semaphore.wait();
 304   }
 305   if (has_operation()) {
 306     HandshakeOperation* op = _operation;
 307     clear_handshake(thread);
 308     if (op != NULL) {
 309       op->do_handshake(thread);
 310     }
 311   }
 312   _semaphore.signal();
 313 }
 314 
 315 void HandshakeState::cancel_inner(JavaThread* thread) {
 316   assert(Thread::current() == thread, "should call from thread");
 317   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
 318 #ifdef DEBUG
 319   {
 320     ThreadsListHandle tlh;
 321     assert(!tlh.includes(_target), "java thread must not be on threads list");
 322   }
 323 #endif
 324   HandshakeOperation* op = _operation;
 325   clear_handshake(thread);
 326   if (op != NULL) {
 327     op->cancel_handshake(thread);
 328   }
 329 }
 330 
 331 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
 332   return SafepointSynchronize::safepoint_safe(target, target->thread_state());
 333 }
 334 
 335 bool HandshakeState::claim_handshake_for_vmthread() {
 336   if (_semaphore.trywait()) {
 337     if (has_operation()) {
 338       _vmthread_holds_semaphore = true;
 339     } else {
 340       _semaphore.signal();
 341     }


< prev index next >