< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 57079 : imported patch 8234796


  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.inline.hpp"
  31 #include "runtime/orderAccess.hpp"
  32 #include "runtime/osThread.hpp"
  33 #include "runtime/semaphore.inline.hpp"
  34 #include "runtime/task.hpp"
  35 #include "runtime/timerTrace.hpp"
  36 #include "runtime/thread.hpp"
  37 #include "runtime/vmThread.hpp"
  38 #include "utilities/formatBuffer.hpp"
  39 #include "utilities/preserveException.hpp"
  40 
  41 class HandshakeOperation: public StackObj {
  42 public:
  43   virtual void do_handshake(JavaThread* thread) = 0;
  44 };
  45 
  46 class HandshakeThreadsOperation: public HandshakeOperation {
  47   static Semaphore _done;
  48   ThreadClosure* _thread_cl;
  49   bool _executed;
  50 public:
  51   HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {}
  52   void do_handshake(JavaThread* thread);
  53   bool thread_has_completed() { return _done.trywait(); }
  54   bool executed() const { return _executed; }
  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 
  75   VM_Handshake(HandshakeThreadsOperation* op) :
  76       _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {}
  77 
  78   void set_handshake(JavaThread* target) {
  79     target->set_handshake_operation(_op);
  80   }
  81 
  82   // This method returns true for threads completed their operation
  83   // and true for threads canceled their operation.
  84   // A cancellation can happen if the thread is exiting.
  85   bool poll_for_completed_thread() { return _op->thread_has_completed(); }
  86 
  87   bool handshake_has_timed_out(jlong start_time);
  88   static void handle_timeout();
  89 };
  90 
  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 class VM_HandshakeOneThread: public VM_Handshake {
 112   JavaThread* _target;
 113  public:
 114   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 115     VM_Handshake(op), _target(target) {}
 116 
 117   void doit() {
 118     DEBUG_ONLY(_op->check_state();)
 119     TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake));
 120 
 121     ThreadsListHandle tlh;
 122     if (tlh.includes(_target)) {
 123       set_handshake(_target);
 124     } else {
 125       log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target));
 126       return;
 127     }
 128 
 129     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
 130     jlong start_time = os::elapsed_counter();
 131     do {
 132       if (handshake_has_timed_out(start_time)) {
 133         handle_timeout();
 134       }
 135 
 136       // We need to re-think this with SMR ThreadsList.
 137       // There is an assumption in the code that the Threads_lock should be
 138       // locked during certain phases.
 139       {
 140         MutexLocker ml(Threads_lock);
 141         _target->handshake_process_by_vmthread();
 142       }
 143     } while (!poll_for_completed_thread());
 144     DEBUG_ONLY(_op->check_state();)
 145   }
 146 
 147   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 148 
 149   bool executed() const { return _op->executed(); }
 150 };
 151 
 152 class VM_HandshakeAllThreads: public VM_Handshake {
 153  public:
 154   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 155 
 156   void doit() {
 157     DEBUG_ONLY(_op->check_state();)
 158     TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake));
 159 
 160     JavaThreadIteratorWithHandle jtiwh;
 161     int number_of_threads_issued = 0;
 162     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 163       set_handshake(thr);
 164       number_of_threads_issued++;
 165     }
 166 
 167     if (number_of_threads_issued < 1) {
 168       log_debug(handshake)("No threads to handshake.");
 169       return;
 170     }
 171 
 172     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 173     const jlong start_time = os::elapsed_counter();
 174     int number_of_threads_completed = 0;


 191             // A new thread on the ThreadsList will not have an operation,
 192             // hence it is skipped in handshake_process_by_vmthread.
 193             thr->handshake_process_by_vmthread();
 194           }
 195       }
 196 
 197       while (poll_for_completed_thread()) {
 198         // Includes canceled operations by exiting threads.
 199         number_of_threads_completed++;
 200       }
 201 
 202     } while (number_of_threads_issued > number_of_threads_completed);
 203     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 204     DEBUG_ONLY(_op->check_state();)
 205   }
 206 
 207   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 208 };
 209 
 210 class VM_HandshakeFallbackOperation : public VM_Operation {
 211   ThreadClosure* _thread_cl;
 212   Thread* _target_thread;
 213   bool _all_threads;
 214   bool _executed;
 215 public:
 216   VM_HandshakeFallbackOperation(ThreadClosure* cl) :
 217       _thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
 218   VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
 219       _thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
 220 
 221   void doit() {
 222     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
 223     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 224       if (_all_threads || t == _target_thread) {
 225         if (t == _target_thread) {
 226           _executed = true;
 227         }
 228         _thread_cl->do_thread(t);
 229       }
 230     }
 231   }
 232 
 233   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 234   bool executed() const { return _executed; }
 235 };
 236 
 237 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
 238   ResourceMark rm;
 239   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 240                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 241   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
 242 
 243   // Only actually execute the operation for non terminated threads.
 244   if (!thread->is_terminated()) {
 245     _thread_cl->do_thread(thread);
 246     _executed = true;
 247   }
 248 
 249   // Use the semaphore to inform the VM thread that we have completed the operation
 250   _done.signal();
 251 }
 252 
 253 void Handshake::execute(ThreadClosure* thread_cl) {
 254   if (ThreadLocalHandshakes) {
 255     HandshakeThreadsOperation cto(thread_cl);
 256     VM_HandshakeAllThreads handshake(&cto);
 257     VMThread::execute(&handshake);
 258   } else {
 259     VM_HandshakeFallbackOperation op(thread_cl);
 260     VMThread::execute(&op);
 261   }
 262 }
 263 
 264 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
 265   if (ThreadLocalHandshakes) {
 266     HandshakeThreadsOperation cto(thread_cl);
 267     VM_HandshakeOneThread handshake(&cto, target);
 268     VMThread::execute(&handshake);
 269     return handshake.executed();
 270   } else {
 271     VM_HandshakeFallbackOperation op(thread_cl, target);
 272     VMThread::execute(&op);
 273     return op.executed();
 274   }
 275 }
 276 
 277 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
 278 
 279 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
 280   _operation = op;
 281   SafepointMechanism::arm_local_poll_release(target);
 282 }
 283 
 284 void HandshakeState::clear_handshake(JavaThread* target) {
 285   _operation = NULL;
 286   SafepointMechanism::disarm_if_needed(target, true /* release */);
 287 }
 288 
 289 void HandshakeState::process_self_inner(JavaThread* thread) {
 290   assert(Thread::current() == thread, "should call from thread");
 291   assert(!thread->is_terminated(), "should not be a terminated thread");




  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.inline.hpp"
  31 #include "runtime/orderAccess.hpp"
  32 #include "runtime/osThread.hpp"
  33 #include "runtime/semaphore.inline.hpp"
  34 #include "runtime/task.hpp"
  35 #include "runtime/timerTrace.hpp"
  36 #include "runtime/thread.hpp"
  37 #include "runtime/vmThread.hpp"
  38 #include "utilities/formatBuffer.hpp"
  39 #include "utilities/preserveException.hpp"
  40 
  41 Semaphore HandshakeOperation::_done(0);






















  42 
  43 class VM_Handshake: public VM_Operation {
  44   const jlong _handshake_timeout;
  45  public:
  46   bool evaluate_at_safepoint() const { return false; }
  47 
  48   bool evaluate_concurrently() const { return false; }
  49 
  50  protected:
  51   HandshakeOperation* const _op;
  52 
  53   VM_Handshake(HandshakeOperation* op) :
  54       _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {}
  55 
  56   void set_handshake(JavaThread* target) {
  57     target->set_handshake_operation(_op);
  58   }
  59 
  60   // This method returns true for threads completed their operation
  61   // and true for threads canceled their operation.
  62   // A cancellation can happen if the thread is exiting.
  63   bool poll_for_completed_thread() { return _op->thread_has_completed(); }
  64 
  65   bool handshake_has_timed_out(jlong start_time);
  66   static void handle_timeout();
  67 };
  68 
  69 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  70   // Check if handshake operation has timed out
  71   if (_handshake_timeout > 0) {
  72     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  73   }
  74   return false;
  75 }
  76 
  77 void VM_Handshake::handle_timeout() {
  78   LogStreamHandle(Warning, handshake) log_stream;
  79   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
  80     if (thr->has_handshake()) {
  81       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
  82       thr->print_thread_state_on(&log_stream);
  83     }
  84   }
  85   log_stream.flush();
  86   fatal("Handshake operation timed out");
  87 }
  88 
  89 class VM_HandshakeOneThread: public VM_Handshake {
  90   JavaThread* _target;
  91  public:
  92   VM_HandshakeOneThread(HandshakeOperation* op, JavaThread* target) :
  93     VM_Handshake(op), _target(target) {}
  94 
  95   void doit() {
  96     DEBUG_ONLY(_op->check_state();)
  97     TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake));
  98 
  99     ThreadsListHandle tlh;
 100     if (tlh.includes(_target)) {
 101       set_handshake(_target);
 102     } else {
 103       log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target));
 104       return;
 105     }
 106 
 107     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
 108     jlong start_time = os::elapsed_counter();
 109     do {
 110       if (handshake_has_timed_out(start_time)) {
 111         handle_timeout();
 112       }
 113 
 114       // We need to re-think this with SMR ThreadsList.
 115       // There is an assumption in the code that the Threads_lock should be
 116       // locked during certain phases.
 117       {
 118         MutexLocker ml(Threads_lock);
 119         _target->handshake_process_by_vmthread();
 120       }
 121     } while (!poll_for_completed_thread());
 122     DEBUG_ONLY(_op->check_state();)
 123   }
 124 
 125   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 126 
 127   bool executed() const { return _op->executed(); }
 128 };
 129 
 130 class VM_HandshakeAllThreads: public VM_Handshake {
 131  public:
 132   VM_HandshakeAllThreads(HandshakeOperation* op) : VM_Handshake(op) {}
 133 
 134   void doit() {
 135     DEBUG_ONLY(_op->check_state();)
 136     TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake));
 137 
 138     JavaThreadIteratorWithHandle jtiwh;
 139     int number_of_threads_issued = 0;
 140     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 141       set_handshake(thr);
 142       number_of_threads_issued++;
 143     }
 144 
 145     if (number_of_threads_issued < 1) {
 146       log_debug(handshake)("No threads to handshake.");
 147       return;
 148     }
 149 
 150     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 151     const jlong start_time = os::elapsed_counter();
 152     int number_of_threads_completed = 0;


 169             // A new thread on the ThreadsList will not have an operation,
 170             // hence it is skipped in handshake_process_by_vmthread.
 171             thr->handshake_process_by_vmthread();
 172           }
 173       }
 174 
 175       while (poll_for_completed_thread()) {
 176         // Includes canceled operations by exiting threads.
 177         number_of_threads_completed++;
 178       }
 179 
 180     } while (number_of_threads_issued > number_of_threads_completed);
 181     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 182     DEBUG_ONLY(_op->check_state();)
 183   }
 184 
 185   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 186 };
 187 
 188 class VM_HandshakeFallbackOperation : public VM_Operation {
 189   HandshakeOperation* _hs_op;
 190   Thread* _target_thread;
 191   bool _all_threads;
 192   bool _executed;
 193 public:
 194   VM_HandshakeFallbackOperation(HandshakeOperation* hs_op) :
 195       _hs_op(hs_op), _target_thread(NULL), _all_threads(true), _executed(false) {}
 196   VM_HandshakeFallbackOperation(HandshakeOperation* hs_op, Thread* target) :
 197       _hs_op(hs_op), _target_thread(target), _all_threads(false), _executed(false) {}
 198 
 199   void doit() {
 200     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
 201     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 202       if (_all_threads || t == _target_thread) {
 203         if (t == _target_thread) {
 204           _executed = true;
 205         }
 206         _hs_op->do_thread(t);
 207       }
 208     }
 209   }
 210 
 211   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 212   bool executed() const { return _executed; }
 213 };
 214 
 215 void HandshakeOperation::do_handshake(JavaThread* thread) {
 216   ResourceMark rm;
 217   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 218                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 219   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
 220 
 221   // Only actually execute the operation for non terminated threads.
 222   if (!thread->is_terminated()) {
 223     do_thread(thread);
 224     _executed = true;
 225   }
 226 
 227   // Use the semaphore to inform the VM thread that we have completed the operation
 228   _done.signal();
 229 }
 230 
 231 void Handshake::execute(HandshakeOperation* hs_op) {
 232   if (ThreadLocalHandshakes) {
 233     VM_HandshakeAllThreads handshake(hs_op);

 234     VMThread::execute(&handshake);
 235   } else {
 236     VM_HandshakeFallbackOperation op(hs_op);
 237     VMThread::execute(&op);
 238   }
 239 }
 240 
 241 bool Handshake::execute(HandshakeOperation* hs_op, JavaThread* target) {
 242   if (ThreadLocalHandshakes) {
 243     VM_HandshakeOneThread handshake(hs_op, target);

 244     VMThread::execute(&handshake);
 245     return handshake.executed();
 246   } else {
 247     VM_HandshakeFallbackOperation op(hs_op, target);
 248     VMThread::execute(&op);
 249     return op.executed();
 250   }
 251 }
 252 
 253 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
 254 
 255 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
 256   _operation = op;
 257   SafepointMechanism::arm_local_poll_release(target);
 258 }
 259 
 260 void HandshakeState::clear_handshake(JavaThread* target) {
 261   _operation = NULL;
 262   SafepointMechanism::disarm_if_needed(target, true /* release */);
 263 }
 264 
 265 void HandshakeState::process_self_inner(JavaThread* thread) {
 266   assert(Thread::current() == thread, "should call from thread");
 267   assert(!thread->is_terminated(), "should not be a terminated thread");


< prev index next >