< prev index next >

src/hotspot/share/runtime/handshake.cpp

Print this page
rev 52283 : [mq]: 8212933


  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   virtual void cancel_handshake(JavaThread* thread) = 0;
  45 };
  46 
  47 class HandshakeThreadsOperation: public HandshakeOperation {
  48   static Semaphore _done;
  49   ThreadClosure* _thread_cl;
  50 
  51 public:
  52   HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
  53   void do_handshake(JavaThread* thread);
  54   void cancel_handshake(JavaThread* thread) { _done.signal(); };
  55 
  56   bool thread_has_completed() { return _done.trywait(); }
  57 
  58 #ifdef ASSERT
  59   void check_state() {
  60     assert(!_done.trywait(), "Must be zero");
  61   }
  62 #endif
  63 };
  64 
  65 Semaphore HandshakeThreadsOperation::_done(0);
  66 
  67 class VM_Handshake: public VM_Operation {
  68   const jlong _handshake_timeout;
  69  public:
  70   bool evaluate_at_safepoint() const { return false; }
  71 
  72   bool evaluate_concurrently() const { return false; }
  73 
  74  protected:
  75   HandshakeThreadsOperation* const _op;


 104     if (thr->has_handshake()) {
 105       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
 106       thr->print_thread_state_on(&log_stream);
 107     }
 108   }
 109   log_stream.flush();
 110   fatal("Handshake operation timed out");
 111 }
 112 
 113 class VM_HandshakeOneThread: public VM_Handshake {
 114   JavaThread* _target;
 115   bool _thread_alive;
 116  public:
 117   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 118     VM_Handshake(op), _target(target), _thread_alive(false) {}
 119 
 120   void doit() {
 121     DEBUG_ONLY(_op->check_state();)
 122     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 123 
 124     {
 125       ThreadsListHandle tlh;
 126       if (tlh.includes(_target)) {
 127         set_handshake(_target);
 128         _thread_alive = true;
 129       }
 130     }
 131 
 132     if (!_thread_alive) {
 133       return;
 134     }
 135 
 136     if (!UseMembar) {
 137       os::serialize_thread_states();
 138     }
 139 
 140     log_trace(handshake)("Thread signaled, begin processing by VMThtread");
 141     jlong start_time = os::elapsed_counter();
 142     do {
 143       if (handshake_has_timed_out(start_time)) {
 144         handle_timeout();
 145       }
 146 
 147       // We need to re-think this with SMR ThreadsList.
 148       // There is an assumption in the code that the Threads_lock should be
 149       // locked during certain phases.

 150       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 151       ThreadsListHandle tlh;
 152       if (tlh.includes(_target)) {
 153         // Warning _target's address might be re-used.
 154         // handshake_process_by_vmthread will check the semaphore for us again.
 155         // Since we can't have more then one handshake in flight a reuse of
 156         // _target's address should be okay since the new thread will not have
 157         // an operation.
 158         _target->handshake_process_by_vmthread();
 159       } else {
 160         // We can't warn here since the thread does cancel_handshake after
 161         // it has been removed from the ThreadsList. So we should just keep
 162         // looping here until while below returns false. If we have a bug,
 163         // then we hang here, which is good for debugging.
 164       }
 165     } while (!poll_for_completed_thread());
 166     DEBUG_ONLY(_op->check_state();)
 167   }
 168 
 169   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 170 
 171   bool thread_alive() const { return _thread_alive; }
 172 };
 173 
 174 class VM_HandshakeAllThreads: public VM_Handshake {
 175  public:
 176   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 177 
 178   void doit() {
 179     DEBUG_ONLY(_op->check_state();)
 180     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 181 

 182     int number_of_threads_issued = 0;
 183     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
 184       set_handshake(thr);
 185       number_of_threads_issued++;
 186     }
 187 
 188     if (number_of_threads_issued < 1) {
 189       log_debug(handshake)("No threads to handshake.");
 190       return;
 191     }
 192 
 193     if (!UseMembar) {
 194       os::serialize_thread_states();
 195     }
 196 
 197     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 198     const jlong start_time = os::elapsed_counter();
 199     int number_of_threads_completed = 0;
 200     do {
 201       // Check if handshake operation has timed out
 202       if (handshake_has_timed_out(start_time)) {
 203         handle_timeout();
 204       }
 205 
 206       // Have VM thread perform the handshake operation for blocked threads.
 207       // Observing a blocked state may of course be transient but the processing is guarded
 208       // by semaphores and we optimistically begin by working on the blocked threads
 209       {
 210           // We need to re-think this with SMR ThreadsList.
 211           // There is an assumption in the code that the Threads_lock should
 212           // be locked during certain phases.

 213           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 214           for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
 215             // A new thread on the ThreadsList will not have an operation,
 216             // hence it is skipped in handshake_process_by_vmthread.
 217             thr->handshake_process_by_vmthread();
 218           }
 219       }
 220 
 221       while (poll_for_completed_thread()) {
 222         // Includes canceled operations by exiting threads.
 223         number_of_threads_completed++;
 224       }
 225 
 226     } while (number_of_threads_issued > number_of_threads_completed);
 227     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 228     DEBUG_ONLY(_op->check_state();)
 229   }
 230 
 231   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 232 };
 233 
 234 class VM_HandshakeFallbackOperation : public VM_Operation {


 245   void doit() {
 246     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 247       if (_all_threads || t == _target_thread) {
 248         if (t == _target_thread) {
 249           _thread_alive = true;
 250         }
 251         _thread_cl->do_thread(t);
 252       }
 253     }
 254   }
 255 
 256   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 257   bool thread_alive() const { return _thread_alive; }
 258 };
 259 
 260 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
 261   ResourceMark rm;
 262   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 263                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 264   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));



 265   _thread_cl->do_thread(thread);

 266 
 267   // Use the semaphore to inform the VM thread that we have completed the operation
 268   _done.signal();
 269 }
 270 
 271 void Handshake::execute(ThreadClosure* thread_cl) {
 272   if (ThreadLocalHandshakes) {
 273     HandshakeThreadsOperation cto(thread_cl);
 274     VM_HandshakeAllThreads handshake(&cto);
 275     VMThread::execute(&handshake);
 276   } else {
 277     VM_HandshakeFallbackOperation op(thread_cl);
 278     VMThread::execute(&op);
 279   }
 280 }
 281 
 282 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
 283   if (ThreadLocalHandshakes) {
 284     HandshakeThreadsOperation cto(thread_cl);
 285     VM_HandshakeOneThread handshake(&cto, target);


 289     VM_HandshakeFallbackOperation op(thread_cl, target);
 290     VMThread::execute(&op);
 291     return op.thread_alive();
 292   }
 293 }
 294 
 295 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
 296 
 297 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
 298   _operation = op;
 299   SafepointMechanism::arm_local_poll_release(target);
 300 }
 301 
 302 void HandshakeState::clear_handshake(JavaThread* target) {
 303   _operation = NULL;
 304   SafepointMechanism::disarm_local_poll_release(target);
 305 }
 306 
 307 void HandshakeState::process_self_inner(JavaThread* thread) {
 308   assert(Thread::current() == thread, "should call from thread");
 309 
 310   if (thread->is_terminated()) {
 311     // If thread is not on threads list but armed, cancel.
 312     thread->cancel_handshake();
 313     return;
 314   }
 315 
 316   CautiouslyPreserveExceptionMark pem(thread);
 317   ThreadInVMForHandshake tivm(thread);
 318   if (!_semaphore.trywait()) {
 319     _semaphore.wait_with_safepoint_check(thread);
 320   }
 321   HandshakeOperation* op = OrderAccess::load_acquire(&_operation);
 322   if (op != NULL) {
 323     // Disarm before execute the operation
 324     clear_handshake(thread);
 325     op->do_handshake(thread);
 326   }
 327   _semaphore.signal();
 328 }
 329 
 330 void HandshakeState::cancel_inner(JavaThread* thread) {
 331   assert(Thread::current() == thread, "should call from thread");
 332   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
 333   HandshakeOperation* op = _operation;
 334   clear_handshake(thread);
 335   if (op != NULL) {
 336     op->cancel_handshake(thread);
 337   }
 338 }
 339 
 340 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
 341   // SafepointSynchronize::safepoint_safe() does not consider an externally
 342   // suspended thread to be safe. However, this function must be called with
 343   // the Threads_lock held so an externally suspended thread cannot be
 344   // resumed thus it is safe.
 345   assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
 346   return SafepointSynchronize::safepoint_safe(target, target->thread_state()) ||
 347          target->is_ext_suspended();
 348 }
 349 
 350 static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
 351   // An externally suspended thread cannot be resumed while the
 352   // Threads_lock is held so it is safe.
 353   // Note that this method is allowed to produce false positives.
 354   assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
 355   if (target->is_ext_suspended()) {
 356     return true;
 357   }



 358   switch (target->thread_state()) {
 359   case _thread_in_native:
 360     // native threads are safe if they have no java stack or have walkable stack
 361     return !target->has_last_Java_frame() || target->frame_anchor()->walkable();
 362 
 363   case _thread_blocked:
 364     return true;
 365 
 366   default:
 367     return false;
 368   }
 369 }
 370 
 371 bool HandshakeState::claim_handshake_for_vmthread() {
 372   if (!_semaphore.trywait()) {
 373     return false;
 374   }
 375   if (has_operation()) {
 376     return true;
 377   }


 385   if (!has_operation()) {
 386     // JT has already cleared its handshake
 387     return;
 388   }
 389 
 390   if (!possibly_vmthread_can_process_handshake(target)) {
 391     // JT is observed in an unsafe state, it must notice the handshake itself
 392     return;
 393   }
 394 
 395   // Claim the semaphore if there still an operation to be executed.
 396   if (!claim_handshake_for_vmthread()) {
 397     return;
 398   }
 399 
 400   // If we own the semaphore at this point and while owning the semaphore
 401   // can observe a safe state the thread cannot possibly continue without
 402   // getting caught by the semaphore.
 403   if (vmthread_can_process_handshake(target)) {
 404     guarantee(!_semaphore.trywait(), "we should already own the semaphore");
 405 
 406     _operation->do_handshake(target);
 407     // Disarm after VM thread have executed the operation.
 408     clear_handshake(target);
 409     // Release the thread
 410   }
 411 
 412   _semaphore.signal();
 413 }


  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 
  50 public:
  51   HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {}
  52   void do_handshake(JavaThread* thread);


  53   bool thread_has_completed() { return _done.trywait(); }
  54 
  55 #ifdef ASSERT
  56   void check_state() {
  57     assert(!_done.trywait(), "Must be zero");
  58   }
  59 #endif
  60 };
  61 
  62 Semaphore HandshakeThreadsOperation::_done(0);
  63 
  64 class VM_Handshake: public VM_Operation {
  65   const jlong _handshake_timeout;
  66  public:
  67   bool evaluate_at_safepoint() const { return false; }
  68 
  69   bool evaluate_concurrently() const { return false; }
  70 
  71  protected:
  72   HandshakeThreadsOperation* const _op;


 101     if (thr->has_handshake()) {
 102       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
 103       thr->print_thread_state_on(&log_stream);
 104     }
 105   }
 106   log_stream.flush();
 107   fatal("Handshake operation timed out");
 108 }
 109 
 110 class VM_HandshakeOneThread: public VM_Handshake {
 111   JavaThread* _target;
 112   bool _thread_alive;
 113  public:
 114   VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
 115     VM_Handshake(op), _target(target), _thread_alive(false) {}
 116 
 117   void doit() {
 118     DEBUG_ONLY(_op->check_state();)
 119     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 120 

 121     ThreadsListHandle tlh;
 122     if (tlh.includes(_target)) {
 123       set_handshake(_target);
 124       _thread_alive = true;
 125     } else {



 126       return;
 127     }
 128 
 129     if (!UseMembar) {
 130       os::serialize_thread_states();
 131     }
 132 
 133     log_trace(handshake)("Thread signaled, begin processing by VMThtread");
 134     jlong start_time = os::elapsed_counter();
 135     do {
 136       if (handshake_has_timed_out(start_time)) {
 137         handle_timeout();
 138       }
 139 
 140       // We need to re-think this with SMR ThreadsList.
 141       // There is an assumption in the code that the Threads_lock should be
 142       // locked during certain phases.
 143       {
 144         MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);







 145         _target->handshake_process_by_vmthread();





 146       }
 147     } while (!poll_for_completed_thread());
 148     DEBUG_ONLY(_op->check_state();)
 149   }
 150 
 151   VMOp_Type type() const { return VMOp_HandshakeOneThread; }
 152 
 153   bool thread_alive() const { return _thread_alive; }
 154 };
 155 
 156 class VM_HandshakeAllThreads: public VM_Handshake {
 157  public:
 158   VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
 159 
 160   void doit() {
 161     DEBUG_ONLY(_op->check_state();)
 162     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 163 
 164     JavaThreadIteratorWithHandle jtiwh;
 165     int number_of_threads_issued = 0;
 166     for ( ; JavaThread *thr = jtiwh.next(); ) {
 167       set_handshake(thr);
 168       number_of_threads_issued++;
 169     }
 170 
 171     if (number_of_threads_issued < 1) {
 172       log_debug(handshake)("No threads to handshake.");
 173       return;
 174     }
 175 
 176     if (!UseMembar) {
 177       os::serialize_thread_states();
 178     }
 179 
 180     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
 181     const jlong start_time = os::elapsed_counter();
 182     int number_of_threads_completed = 0;
 183     do {
 184       // Check if handshake operation has timed out
 185       if (handshake_has_timed_out(start_time)) {
 186         handle_timeout();
 187       }
 188 
 189       // Have VM thread perform the handshake operation for blocked threads.
 190       // Observing a blocked state may of course be transient but the processing is guarded
 191       // by semaphores and we optimistically begin by working on the blocked threads
 192       {
 193           // We need to re-think this with SMR ThreadsList.
 194           // There is an assumption in the code that the Threads_lock should
 195           // be locked during certain phases.
 196           jtiwh.rewind();
 197           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
 198           for ( ; JavaThread *thr = jtiwh.next(); ) {
 199             // A new thread on the ThreadsList will not have an operation,
 200             // hence it is skipped in handshake_process_by_vmthread.
 201             thr->handshake_process_by_vmthread();
 202           }
 203       }
 204 
 205       while (poll_for_completed_thread()) {
 206         // Includes canceled operations by exiting threads.
 207         number_of_threads_completed++;
 208       }
 209 
 210     } while (number_of_threads_issued > number_of_threads_completed);
 211     assert(number_of_threads_issued == number_of_threads_completed, "Must be the same");
 212     DEBUG_ONLY(_op->check_state();)
 213   }
 214 
 215   VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
 216 };
 217 
 218 class VM_HandshakeFallbackOperation : public VM_Operation {


 229   void doit() {
 230     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 231       if (_all_threads || t == _target_thread) {
 232         if (t == _target_thread) {
 233           _thread_alive = true;
 234         }
 235         _thread_cl->do_thread(t);
 236       }
 237     }
 238   }
 239 
 240   VMOp_Type type() const { return VMOp_HandshakeFallback; }
 241   bool thread_alive() const { return _thread_alive; }
 242 };
 243 
 244 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
 245   ResourceMark rm;
 246   FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
 247                                p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
 248   TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
 249 
 250   // Only actually execute the operation for non terminated threads.
 251   if (!thread->is_terminated()) {
 252     _thread_cl->do_thread(thread);
 253   }
 254 
 255   // Use the semaphore to inform the VM thread that we have completed the operation
 256   _done.signal();
 257 }
 258 
 259 void Handshake::execute(ThreadClosure* thread_cl) {
 260   if (ThreadLocalHandshakes) {
 261     HandshakeThreadsOperation cto(thread_cl);
 262     VM_HandshakeAllThreads handshake(&cto);
 263     VMThread::execute(&handshake);
 264   } else {
 265     VM_HandshakeFallbackOperation op(thread_cl);
 266     VMThread::execute(&op);
 267   }
 268 }
 269 
 270 bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) {
 271   if (ThreadLocalHandshakes) {
 272     HandshakeThreadsOperation cto(thread_cl);
 273     VM_HandshakeOneThread handshake(&cto, target);


 277     VM_HandshakeFallbackOperation op(thread_cl, target);
 278     VMThread::execute(&op);
 279     return op.thread_alive();
 280   }
 281 }
 282 
 283 HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {}
 284 
 285 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
 286   _operation = op;
 287   SafepointMechanism::arm_local_poll_release(target);
 288 }
 289 
 290 void HandshakeState::clear_handshake(JavaThread* target) {
 291   _operation = NULL;
 292   SafepointMechanism::disarm_local_poll_release(target);
 293 }
 294 
 295 void HandshakeState::process_self_inner(JavaThread* thread) {
 296   assert(Thread::current() == thread, "should call from thread");
 297   assert(!thread->is_terminated(), "should not be a terminated thread");





 298 
 299   CautiouslyPreserveExceptionMark pem(thread);
 300   ThreadInVMForHandshake tivm(thread);
 301   if (!_semaphore.trywait()) {
 302     _semaphore.wait_with_safepoint_check(thread);
 303   }
 304   HandshakeOperation* op = OrderAccess::load_acquire(&_operation);
 305   if (op != NULL) {
 306     // Disarm before execute the operation
 307     clear_handshake(thread);
 308     op->do_handshake(thread);
 309   }
 310   _semaphore.signal();
 311 }
 312 










 313 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
 314   // SafepointSynchronize::safepoint_safe() does not consider an externally
 315   // suspended thread to be safe. However, this function must be called with
 316   // the Threads_lock held so an externally suspended thread cannot be
 317   // resumed thus it is safe.
 318   assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
 319   return SafepointSynchronize::safepoint_safe(target, target->thread_state()) ||
 320          target->is_ext_suspended() || target->is_terminated();
 321 }
 322 
 323 static bool possibly_vmthread_can_process_handshake(JavaThread* target) {
 324   // An externally suspended thread cannot be resumed while the
 325   // Threads_lock is held so it is safe.
 326   // Note that this method is allowed to produce false positives.
 327   assert(Threads_lock->owned_by_self(), "Not holding Threads_lock.");
 328   if (target->is_ext_suspended()) {
 329     return true;
 330   }
 331   if (target->is_terminated()) {
 332     return true;
 333   }
 334   switch (target->thread_state()) {
 335   case _thread_in_native:
 336     // native threads are safe if they have no java stack or have walkable stack
 337     return !target->has_last_Java_frame() || target->frame_anchor()->walkable();
 338 
 339   case _thread_blocked:
 340     return true;
 341 
 342   default:
 343     return false;
 344   }
 345 }
 346 
 347 bool HandshakeState::claim_handshake_for_vmthread() {
 348   if (!_semaphore.trywait()) {
 349     return false;
 350   }
 351   if (has_operation()) {
 352     return true;
 353   }


 361   if (!has_operation()) {
 362     // JT has already cleared its handshake
 363     return;
 364   }
 365 
 366   if (!possibly_vmthread_can_process_handshake(target)) {
 367     // JT is observed in an unsafe state, it must notice the handshake itself
 368     return;
 369   }
 370 
 371   // Claim the semaphore if there still an operation to be executed.
 372   if (!claim_handshake_for_vmthread()) {
 373     return;
 374   }
 375 
 376   // If we own the semaphore at this point and while owning the semaphore
 377   // can observe a safe state the thread cannot possibly continue without
 378   // getting caught by the semaphore.
 379   if (vmthread_can_process_handshake(target)) {
 380     guarantee(!_semaphore.trywait(), "we should already own the semaphore");

 381     _operation->do_handshake(target);
 382     // Disarm after VM thread have executed the operation.
 383     clear_handshake(target);
 384     // Release the thread
 385   }
 386 
 387   _semaphore.signal();
 388 }
< prev index next >