< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 57079 : imported patch 8234796
rev 57080 : [mq]: 8234742-v2


  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  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.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 


  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;
 153     do {
 154       // Check if handshake operation has timed out
 155       if (handshake_has_timed_out(start_time)) {
 156         handle_timeout();
 157       }
 158 
 159       // Have VM thread perform the handshake operation for blocked threads.
 160       // Observing a blocked state may of course be transient but the processing is guarded
 161       // by semaphores and we optimistically begin by working on the blocked threads
 162       {
 163           // We need to re-think this with SMR ThreadsList.
 164           // There is an assumption in the code that the Threads_lock should
 165           // be locked during certain phases.
 166           jtiwh.rewind();
 167           MutexLocker ml(Threads_lock);
 168           for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 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);


 305 
 306   case _thread_blocked:
 307     return true;
 308 
 309   default:
 310     return false;
 311   }
 312 }
 313 
 314 bool HandshakeState::claim_handshake_for_vmthread() {
 315   if (!_semaphore.trywait()) {
 316     return false;
 317   }
 318   if (has_operation()) {
 319     return true;
 320   }
 321   _semaphore.signal();
 322   return false;
 323 }
 324 
 325 void HandshakeState::process_by_vmthread(JavaThread* target) {
 326   assert(Thread::current()->is_VM_thread(), "should call from vm thread");
 327   // Threads_lock must be held here, but that is assert()ed in
 328   // possibly_vmthread_can_process_handshake().
 329 
 330   if (!has_operation()) {
 331     // JT has already cleared its handshake
 332     return;
 333   }
 334 
 335   if (!possibly_vmthread_can_process_handshake(target)) {
 336     // JT is observed in an unsafe state, it must notice the handshake itself
 337     return;
 338   }
 339 
 340   // Claim the semaphore if there still an operation to be executed.
 341   if (!claim_handshake_for_vmthread()) {
 342     return;
 343   }
 344 
 345   // If we own the semaphore at this point and while owning the semaphore
 346   // can observe a safe state the thread cannot possibly continue without
 347   // getting caught by the semaphore.

 348   if (vmthread_can_process_handshake(target)) {
 349     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
 350     log_trace(handshake)("Processing handshake by VMThtread");
 351     _operation->do_handshake(target);
 352     // Disarm after VM thread have executed the operation.
 353     clear_handshake(target);
 354     // Release the thread
 355   }
 356 

 357   _semaphore.signal();


 358 }


  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  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.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/thread.hpp"
  36 #include "runtime/vmThread.hpp"
  37 #include "utilities/formatBuffer.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 Semaphore HandshakeOperation::_done(0);
  41 
  42 class VM_Handshake: public VM_Operation {
  43   const jlong _handshake_timeout;
  44  public:
  45   bool evaluate_at_safepoint() const { return false; }
  46 
  47   bool evaluate_concurrently() const { return false; }
  48 
  49  protected:
  50   HandshakeOperation* const _op;
  51 
  52   VM_Handshake(HandshakeOperation* op) :
  53       _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {}
  54 


  68 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
  69   // Check if handshake operation has timed out
  70   if (_handshake_timeout > 0) {
  71     return os::elapsed_counter() >= (start_time + _handshake_timeout);
  72   }
  73   return false;
  74 }
  75 
  76 void VM_Handshake::handle_timeout() {
  77   LogStreamHandle(Warning, handshake) log_stream;
  78   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
  79     if (thr->has_handshake()) {
  80       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
  81       thr->print_thread_state_on(&log_stream);
  82     }
  83   }
  84   log_stream.flush();
  85   fatal("Handshake operation timed out");
  86 }
  87 
  88 static void log_handshake_info(jlong start_time_ns, const char* name, int targets, int vmt_executed, const char* extra) {
  89   if (start_time_ns != 0) {
  90     jlong completion_time = os::javaTimeNanos() - start_time_ns;
  91     log_info(handshake)("Handshake \"%s\", Targeted threads: %d, Executed by targeted threads: %d, Total completion time: " JLONG_FORMAT " ns%s",
  92                         name, targets, targets - vmt_executed, completion_time, extra);
  93   }
  94 }
  95 
  96 class VM_HandshakeOneThread: public VM_Handshake {
  97   JavaThread* _target;
  98  public:
  99   VM_HandshakeOneThread(HandshakeOperation* op, JavaThread* target) :
 100     VM_Handshake(op), _target(target) {}
 101 
 102   void doit() {
 103     DEBUG_ONLY(_op->check_state();)
 104 
 105     jlong start_time_ns = 0;
 106     if (log_is_enabled(Info, handshake)) {
 107       start_time_ns = os::javaTimeNanos();
 108     }
 109 
 110     ThreadsListHandle tlh;
 111     if (tlh.includes(_target)) {
 112       set_handshake(_target);
 113     } else {
 114       log_handshake_info(start_time_ns, _op->name(), 0, 0, " (thread dead)");
 115       return;
 116     }
 117 
 118     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
 119     jlong timeout_start_time = os::elapsed_counter();
 120     bool by_vm_thread = false;
 121     do {
 122       if (handshake_has_timed_out(timeout_start_time)) {
 123         handle_timeout();
 124       }
 125 
 126       // We need to re-think this with SMR ThreadsList.
 127       // There is an assumption in the code that the Threads_lock should be
 128       // locked during certain phases.
 129       {
 130         MutexLocker ml(Threads_lock);
 131         by_vm_thread = _target->handshake_process_by_vmthread();
 132       }
 133     } while (!poll_for_completed_thread());
 134     DEBUG_ONLY(_op->check_state();)
 135     log_handshake_info(start_time_ns, _op->name(), 1, by_vm_thread ? 1 : 0, "");
 136   }
 137 
 138   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 139 
 140   bool executed() const { return _op->executed(); }
 141 };
 142 
 143 class VM_HandshakeAllThreads: public VM_Handshake {
 144  public:
 145   VM_HandshakeAllThreads(HandshakeOperation* op) : VM_Handshake(op) {}
 146 
 147   void doit() {
 148     DEBUG_ONLY(_op->check_state();)
 149 
 150     jlong start_time_ns = 0;
 151     if (log_is_enabled(Info, handshake)) {
 152       start_time_ns = os::javaTimeNanos();
 153     }
 154     int handshake_executed_by_vm_thread = 0;
 155 
 156     JavaThreadIteratorWithHandle jtiwh;
 157     int number_of_threads_issued = 0;
 158     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 159       set_handshake(thr);
 160       number_of_threads_issued++;
 161     }
 162 
 163     if (number_of_threads_issued < 1) {
 164       log_handshake_info(start_time_ns, _op->name(), 0, 0, " (no threads)");
 165       return;
 166     }
 167 
 168     log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 169     const jlong start_time = os::elapsed_counter();
 170     int number_of_threads_completed = 0;
 171     do {
 172       // Check if handshake operation has timed out
 173       if (handshake_has_timed_out(start_time)) {
 174         handle_timeout();
 175       }
 176 
 177       // Have VM thread perform the handshake operation for blocked threads.
 178       // Observing a blocked state may of course be transient but the processing is guarded
 179       // by semaphores and we optimistically begin by working on the blocked threads
 180       {
 181           // We need to re-think this with SMR ThreadsList.
 182           // There is an assumption in the code that the Threads_lock should
 183           // be locked during certain phases.
 184           jtiwh.rewind();
 185           MutexLocker ml(Threads_lock);
 186           for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
 187             // A new thread on the ThreadsList will not have an operation,
 188             // hence it is skipped in handshake_process_by_vmthread.
 189             if (thr->handshake_process_by_vmthread()) {
 190               handshake_executed_by_vm_thread++;
 191             }
 192           }
 193       }
 194 
 195       while (poll_for_completed_thread()) {
 196         // Includes canceled operations by exiting threads.
 197         number_of_threads_completed++;
 198       }
 199 
 200     } while (number_of_threads_issued > number_of_threads_completed);
 201     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 202     DEBUG_ONLY(_op->check_state();)
 203 
 204     log_handshake_info(start_time_ns, _op->name(), number_of_threads_issued, handshake_executed_by_vm_thread, "");
 205   }
 206 
 207   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 208 };
 209 
 210 class VM_HandshakeFallbackOperation : public VM_Operation {
 211   HandshakeOperation* _hs_op;
 212   Thread* _target_thread;
 213   bool _all_threads;
 214   bool _executed;
 215 public:
 216   VM_HandshakeFallbackOperation(HandshakeOperation* hs_op) :
 217       _hs_op(hs_op), _target_thread(NULL), _all_threads(true), _executed(false) {}
 218   VM_HandshakeFallbackOperation(HandshakeOperation* hs_op, Thread* target) :
 219       _hs_op(hs_op), _target_thread(target), _all_threads(false), _executed(false) {}
 220 
 221   void doit() {
 222     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation, operation: %s", name());
 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         _hs_op->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 HandshakeOperation::do_handshake(JavaThread* thread) {
 238   jlong start_time_ns = 0;
 239   if (log_is_enabled(Debug, handshake, task)) {
 240     start_time_ns = os::javaTimeNanos();
 241   }
 242 
 243   // Only actually execute the operation for non terminated threads.
 244   if (!thread->is_terminated()) {
 245     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   if (start_time_ns != 0) {
 253     jlong completion_time = os::javaTimeNanos() - start_time_ns;
 254     log_debug(handshake, task)("Operation: %s for thread " PTR_FORMAT ", is_vm_thread: %s, completed in " JLONG_FORMAT " ns",
 255                                name(), p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()), completion_time);
 256   }
 257 }
 258 
 259 void Handshake::execute(HandshakeOperation* hs_op) {
 260   if (ThreadLocalHandshakes) {
 261     VM_HandshakeAllThreads handshake(hs_op);
 262     VMThread::execute(&handshake);
 263   } else {
 264     VM_HandshakeFallbackOperation op(hs_op);
 265     VMThread::execute(&op);
 266   }
 267 }
 268 
 269 bool Handshake::execute(HandshakeOperation* hs_op, JavaThread* target) {
 270   if (ThreadLocalHandshakes) {
 271     VM_HandshakeOneThread handshake(hs_op, target);
 272     VMThread::execute(&handshake);
 273     return handshake.executed();
 274   } else {
 275     VM_HandshakeFallbackOperation op(hs_op, target);
 276     VMThread::execute(&op);


 333 
 334   case _thread_blocked:
 335     return true;
 336 
 337   default:
 338     return false;
 339   }
 340 }
 341 
 342 bool HandshakeState::claim_handshake_for_vmthread() {
 343   if (!_semaphore.trywait()) {
 344     return false;
 345   }
 346   if (has_operation()) {
 347     return true;
 348   }
 349   _semaphore.signal();
 350   return false;
 351 }
 352 
 353 bool HandshakeState::process_by_vmthread(JavaThread* target) {
 354   assert(Thread::current()->is_VM_thread(), "should call from vm thread");
 355   // Threads_lock must be held here, but that is assert()ed in
 356   // possibly_vmthread_can_process_handshake().
 357 
 358   if (!has_operation()) {
 359     // JT has already cleared its handshake
 360     return false;
 361   }
 362 
 363   if (!possibly_vmthread_can_process_handshake(target)) {
 364     // JT is observed in an unsafe state, it must notice the handshake itself
 365     return false;
 366   }
 367 
 368   // Claim the semaphore if there still an operation to be executed.
 369   if (!claim_handshake_for_vmthread()) {
 370     return false;
 371   }
 372 
 373   // If we own the semaphore at this point and while owning the semaphore
 374   // can observe a safe state the thread cannot possibly continue without
 375   // getting caught by the semaphore.
 376   bool executed = false;
 377   if (vmthread_can_process_handshake(target)) {
 378     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
 379     log_trace(handshake)("Processing handshake by VMThtread");
 380     _operation->do_handshake(target);
 381     // Disarm after VM thread have executed the operation.
 382     clear_handshake(target);
 383     executed = true;
 384   }
 385 
 386   // Release the thread
 387   _semaphore.signal();
 388 
 389   return executed;
 390 }
< prev index next >