src/hotspot/share/runtime/handshake.cpp
changeset 47881 0ce0ac68ace7
child 48105 8d15b1369c7a
equal deleted inserted replaced
47824:cf127be65014 47881:0ce0ac68ace7
       
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    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.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;
       
    62   const jlong _handshake_timeout;
       
    63  public:
       
    64   bool evaluate_at_safepoint() const { return false; }
       
    65 
       
    66   bool evaluate_concurrently() const { return false; }
       
    67 
       
    68  protected:
       
    69 
       
    70   VM_Handshake(HandshakeThreadsOperation* op) :
       
    71       _op(op),
       
    72       _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)) {}
       
    73 
       
    74   void set_handshake(JavaThread* target) {
       
    75     target->set_handshake_operation(_op);
       
    76   }
       
    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));
       
   236   _thread_cl->do_thread(thread);
       
   237 
       
   238   // Use the semaphore to inform the VM thread that we have completed the operation
       
   239   _done.signal();
       
   240 }
       
   241 
       
   242 void Handshake::execute(ThreadClosure* thread_cl) {
       
   243   if (ThreadLocalHandshakes) {
       
   244     HandshakeThreadsOperation cto(thread_cl);
       
   245     VM_HandshakeAllThreads handshake(&cto);
       
   246     VMThread::execute(&handshake);
       
   247   } else {
       
   248     VM_HandshakeFallbackOperation op(thread_cl);
       
   249     VMThread::execute(&op);
       
   250   }
       
   251 }
       
   252 
       
   253 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
       
   254   if (ThreadLocalHandshakes) {
       
   255     HandshakeThreadsOperation cto(thread_cl);
       
   256     VM_HandshakeOneThread handshake(&cto, target);
       
   257     VMThread::execute(&handshake);
       
   258     return handshake.thread_alive();
       
   259   } else {
       
   260     VM_HandshakeFallbackOperation op(thread_cl, target);
       
   261     VMThread::execute(&op);
       
   262     return op.thread_alive();
       
   263   }
       
   264 }
       
   265 
       
   266 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _vmthread_holds_semaphore(false), _thread_in_process_handshake(false) {}
       
   267 
       
   268 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
       
   269   _operation = op;
       
   270   SafepointMechanism::arm_local_poll(target);
       
   271 }
       
   272 
       
   273 void HandshakeState::clear_handshake(JavaThread* target) {
       
   274   _operation = NULL;
       
   275   SafepointMechanism::disarm_local_poll(target);
       
   276 }
       
   277 
       
   278 void HandshakeState::process_self_inner(JavaThread* thread) {
       
   279   assert(Thread::current() == thread, "should call from thread");
       
   280   CautiouslyPreserveExceptionMark pem(thread);
       
   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     }
       
   323   }
       
   324   return _vmthread_holds_semaphore;
       
   325 }
       
   326 
       
   327 void HandshakeState::process_by_vmthread(JavaThread* target) {
       
   328   assert(Thread::current()->is_VM_thread(), "should call from vm thread");
       
   329 
       
   330   if (!has_operation()) {
       
   331     // JT has already cleared its handshake
       
   332     return;
       
   333   }
       
   334 
       
   335   if (!vmthread_can_process_handshake(target)) {
       
   336     // JT is observed in an unsafe state, it must notice the handshake itself
       
   337     return;
       
   338   }
       
   339 
       
   340   // If we own the semaphore at this point and while owning the semaphore
       
   341   // can observe a safe state the thread cannot possibly continue without
       
   342   // getting caught by the semaphore.
       
   343   if (claim_handshake_for_vmthread() && vmthread_can_process_handshake(target)) {
       
   344     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
       
   345 
       
   346     _operation->do_handshake(target);
       
   347     clear_handshake(target);
       
   348     _vmthread_holds_semaphore = false;
       
   349     // Release the thread
       
   350     _semaphore.signal();
       
   351   }
       
   352 }