src/hotspot/share/runtime/handshake.cpp
changeset 55625 f7e8dbb77156
parent 54623 1126f0607c70
child 57699 4aea554692aa
equal deleted inserted replaced
55624:cb90a20eb99a 55625:f7e8dbb77156
    44 };
    44 };
    45 
    45 
    46 class HandshakeThreadsOperation: public HandshakeOperation {
    46 class HandshakeThreadsOperation: public HandshakeOperation {
    47   static Semaphore _done;
    47   static Semaphore _done;
    48   ThreadClosure* _thread_cl;
    48   ThreadClosure* _thread_cl;
    49 
    49   bool _executed;
    50 public:
    50 public:
    51   HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
    51   HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {}
    52   void do_handshake(JavaThread* thread);
    52   void do_handshake(JavaThread* thread);
    53   bool thread_has_completed() { return _done.trywait(); }
    53   bool thread_has_completed() { return _done.trywait(); }
       
    54   bool executed() const { return _executed; }
    54 
    55 
    55 #ifdef ASSERT
    56 #ifdef ASSERT
    56   void check_state() {
    57   void check_state() {
    57     assert(!_done.trywait(), "Must be zero");
    58     assert(!_done.trywait(), "Must be zero");
    58   }
    59   }
   107   fatal("Handshake operation timed out");
   108   fatal("Handshake operation timed out");
   108 }
   109 }
   109 
   110 
   110 class VM_HandshakeOneThread: public VM_Handshake {
   111 class VM_HandshakeOneThread: public VM_Handshake {
   111   JavaThread* _target;
   112   JavaThread* _target;
   112   bool _thread_alive;
       
   113  public:
   113  public:
   114   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
   114   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
   115     VM_Handshake(op), _target(target), _thread_alive(false) {}
   115     VM_Handshake(op), _target(target) {}
   116 
   116 
   117   void doit() {
   117   void doit() {
   118     DEBUG_ONLY(_op->check_state();)
   118     DEBUG_ONLY(_op->check_state();)
   119     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
   119     TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake));
   120 
   120 
   121     ThreadsListHandle tlh;
   121     ThreadsListHandle tlh;
   122     if (tlh.includes(_target)) {
   122     if (tlh.includes(_target)) {
   123       set_handshake(_target);
   123       set_handshake(_target);
   124       _thread_alive = true;
       
   125     } else {
   124     } else {
       
   125       log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target));
   126       return;
   126       return;
   127     }
   127     }
   128 
   128 
   129     log_trace(handshake)("Thread signaled, begin processing by VMThtread");
   129     log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target));
   130     jlong start_time = os::elapsed_counter();
   130     jlong start_time = os::elapsed_counter();
   131     do {
   131     do {
   132       if (handshake_has_timed_out(start_time)) {
   132       if (handshake_has_timed_out(start_time)) {
   133         handle_timeout();
   133         handle_timeout();
   134       }
   134       }
   144     DEBUG_ONLY(_op->check_state();)
   144     DEBUG_ONLY(_op->check_state();)
   145   }
   145   }
   146 
   146 
   147   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
   147   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
   148 
   148 
   149   bool thread_alive() const { return _thread_alive; }
   149   bool executed() const { return _op->executed(); }
   150 };
   150 };
   151 
   151 
   152 class VM_HandshakeAllThreads: public VM_Handshake {
   152 class VM_HandshakeAllThreads: public VM_Handshake {
   153  public:
   153  public:
   154   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
   154   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
   155 
   155 
   156   void doit() {
   156   void doit() {
   157     DEBUG_ONLY(_op->check_state();)
   157     DEBUG_ONLY(_op->check_state();)
   158     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
   158     TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake));
   159 
   159 
   160     JavaThreadIteratorWithHandle jtiwh;
   160     JavaThreadIteratorWithHandle jtiwh;
   161     int number_of_threads_issued = 0;
   161     int number_of_threads_issued = 0;
   162     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
   162     for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {
   163       set_handshake(thr);
   163       set_handshake(thr);
   209 
   209 
   210 class VM_HandshakeFallbackOperation : public VM_Operation {
   210 class VM_HandshakeFallbackOperation : public VM_Operation {
   211   ThreadClosure* _thread_cl;
   211   ThreadClosure* _thread_cl;
   212   Thread* _target_thread;
   212   Thread* _target_thread;
   213   bool _all_threads;
   213   bool _all_threads;
   214   bool _thread_alive;
   214   bool _executed;
   215 public:
   215 public:
   216   VM_HandshakeFallbackOperation(ThreadClosure* cl) :
   216   VM_HandshakeFallbackOperation(ThreadClosure* cl) :
   217       _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
   217       _thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
   218   VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
   218   VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
   219       _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
   219       _thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
   220 
   220 
   221   void doit() {
   221   void doit() {
       
   222     log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation");
   222     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
   223     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
   223       if (_all_threads || t == _target_thread) {
   224       if (_all_threads || t == _target_thread) {
   224         if (t == _target_thread) {
   225         if (t == _target_thread) {
   225           _thread_alive = true;
   226           _executed = true;
   226         }
   227         }
   227         _thread_cl->do_thread(t);
   228         _thread_cl->do_thread(t);
   228       }
   229       }
   229     }
   230     }
   230   }
   231   }
   231 
   232 
   232   VMOp_Type type() const { return VMOp_HandshakeFallback; }
   233   VMOp_Type type() const { return VMOp_HandshakeFallback; }
   233   bool thread_alive() const { return _thread_alive; }
   234   bool executed() const { return _executed; }
   234 };
   235 };
   235 
   236 
   236 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
   237 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
   237   ResourceMark rm;
   238   ResourceMark rm;
   238   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
   239   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
   240   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
   241   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
   241 
   242 
   242   // Only actually execute the operation for non terminated threads.
   243   // Only actually execute the operation for non terminated threads.
   243   if (!thread->is_terminated()) {
   244   if (!thread->is_terminated()) {
   244     _thread_cl->do_thread(thread);
   245     _thread_cl->do_thread(thread);
       
   246     _executed = true;
   245   }
   247   }
   246 
   248 
   247   // Use the semaphore to inform the VM thread that we have completed the operation
   249   // Use the semaphore to inform the VM thread that we have completed the operation
   248   _done.signal();
   250   _done.signal();
   249 }
   251 }
   262 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
   264 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
   263   if (ThreadLocalHandshakes) {
   265   if (ThreadLocalHandshakes) {
   264     HandshakeThreadsOperation cto(thread_cl);
   266     HandshakeThreadsOperation cto(thread_cl);
   265     VM_HandshakeOneThread handshake(&cto, target);
   267     VM_HandshakeOneThread handshake(&cto, target);
   266     VMThread::execute(&handshake);
   268     VMThread::execute(&handshake);
   267     return handshake.thread_alive();
   269     return handshake.executed();
   268   } else {
   270   } else {
   269     VM_HandshakeFallbackOperation op(thread_cl, target);
   271     VM_HandshakeFallbackOperation op(thread_cl, target);
   270     VMThread::execute(&op);
   272     VMThread::execute(&op);
   271     return op.thread_alive();
   273     return op.executed();
   272   }
   274   }
   273 }
   275 }
   274 
   276 
   275 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
   277 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
   276 
   278 
   367   // If we own the semaphore at this point and while owning the semaphore
   369   // If we own the semaphore at this point and while owning the semaphore
   368   // can observe a safe state the thread cannot possibly continue without
   370   // can observe a safe state the thread cannot possibly continue without
   369   // getting caught by the semaphore.
   371   // getting caught by the semaphore.
   370   if (vmthread_can_process_handshake(target)) {
   372   if (vmthread_can_process_handshake(target)) {
   371     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
   373     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
       
   374     log_trace(handshake)("Processing handshake by VMThtread");
   372     _operation->do_handshake(target);
   375     _operation->do_handshake(target);
   373     // Disarm after VM thread have executed the operation.
   376     // Disarm after VM thread have executed the operation.
   374     clear_handshake(target);
   377     clear_handshake(target);
   375     // Release the thread
   378     // Release the thread
   376   }
   379   }