src/hotspot/share/prims/jvmtiRawMonitor.cpp
changeset 59105 76ae9aa0e794
parent 58509 7b41c88f8432
child 59247 56bf71d64d51
equal deleted inserted replaced
59104:046e4024e55a 59105:76ae9aa0e794
   172     ev->unpark();
   172     ev->unpark();
   173   }
   173   }
   174   return;
   174   return;
   175 }
   175 }
   176 
   176 
   177 int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
   177 inline void JvmtiRawMonitor::enqueue_waiter(QNode& node) {
   178   guarantee(_owner == self  , "invariant");
       
   179   guarantee(_recursions == 0, "invariant");
       
   180 
       
   181   QNode node(self);
       
   182   node._notified = 0;
   178   node._notified = 0;
   183   node._t_state = QNode::TS_WAIT;
   179   node._t_state = QNode::TS_WAIT;
   184 
       
   185   RawMonitor_lock->lock_without_safepoint_check();
   180   RawMonitor_lock->lock_without_safepoint_check();
   186   node._next = _wait_set;
   181   node._next = _wait_set;
   187   _wait_set = &node;
   182   _wait_set = &node;
   188   RawMonitor_lock->unlock();
   183   RawMonitor_lock->unlock();
   189 
   184 }
   190   simple_exit(self);
   185 
   191   guarantee(_owner != self, "invariant");
   186 inline void JvmtiRawMonitor::dequeue_waiter(QNode& node) {
   192 
       
   193   int ret = OS_OK;
       
   194   if (millis <= 0) {
       
   195     self->_ParkEvent->park();
       
   196   } else {
       
   197     ret = self->_ParkEvent->park(millis);
       
   198   }
       
   199 
       
   200   // If thread still resides on the waitset then unlink it.
   187   // If thread still resides on the waitset then unlink it.
   201   // Double-checked locking -- the usage is safe in this context
   188   // Double-checked locking -- the usage is safe in this context
   202   // as _t_state is volatile and the lock-unlock operators are
   189   // as _t_state is volatile and the lock-unlock operators are
   203   // serializing (barrier-equivalent).
   190   // serializing (barrier-equivalent).
   204 
   191 
   223     }
   210     }
   224     RawMonitor_lock->unlock();
   211     RawMonitor_lock->unlock();
   225   }
   212   }
   226 
   213 
   227   guarantee(node._t_state == QNode::TS_RUN, "invariant");
   214   guarantee(node._t_state == QNode::TS_RUN, "invariant");
       
   215 }
       
   216 
       
   217 // simple_wait is not quite so simple as we have to deal with the interaction
       
   218 // with the Thread interrupt state, which resides in the java.lang.Thread object.
       
   219 // That state must only be accessed while _thread_in_vm and requires proper thread-state
       
   220 // transitions. However, we cannot perform such transitions whilst we hold the RawMonitor,
       
   221 // else we can deadlock with the VMThread (which may also use RawMonitors as part of
       
   222 // executing various callbacks).
       
   223 // Returns M_OK usually, but M_INTERRUPTED if the thread is a JavaThread and was
       
   224 // interrupted.
       
   225 int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
       
   226   guarantee(_owner == self  , "invariant");
       
   227   guarantee(_recursions == 0, "invariant");
       
   228 
       
   229   QNode node(self);
       
   230   enqueue_waiter(node);
       
   231 
       
   232   simple_exit(self);
       
   233   guarantee(_owner != self, "invariant");
       
   234 
       
   235   int ret = M_OK;
       
   236   if (self->is_Java_thread()) {
       
   237     JavaThread* jt = (JavaThread*) self;
       
   238     // Transition to VM so we can check interrupt state
       
   239     ThreadInVMfromNative tivm(jt);
       
   240     if (jt->is_interrupted(true)) {
       
   241         ret = M_INTERRUPTED;
       
   242     } else {
       
   243       ThreadBlockInVM tbivm(jt);
       
   244       jt->set_suspend_equivalent();
       
   245       if (millis <= 0) {
       
   246         self->_ParkEvent->park();
       
   247       } else {
       
   248         self->_ParkEvent->park(millis);
       
   249       }
       
   250       // Return to VM before post-check of interrupt state
       
   251     }
       
   252     if (jt->is_interrupted(true)) {
       
   253       ret = M_INTERRUPTED;
       
   254     }
       
   255   } else {
       
   256     if (millis <= 0) {
       
   257       self->_ParkEvent->park();
       
   258     } else {
       
   259       self->_ParkEvent->park(millis);
       
   260     }
       
   261   }
       
   262 
       
   263   dequeue_waiter(node);
       
   264 
   228   simple_enter(self);
   265   simple_enter(self);
   229 
       
   230   guarantee(_owner == self, "invariant");
   266   guarantee(_owner == self, "invariant");
   231   guarantee(_recursions == 0, "invariant");
   267   guarantee(_recursions == 0, "invariant");
       
   268 
   232   return ret;
   269   return ret;
   233 }
   270 }
   234 
   271 
   235 void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
   272 void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
   236   guarantee(_owner == self, "invariant");
   273   guarantee(_owner == self, "invariant");
   349   }
   386   }
   350 
   387 
   351   return M_OK;
   388   return M_OK;
   352 }
   389 }
   353 
   390 
   354 // All JavaThreads will enter here with state _thread_blocked
   391 int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
   355 
       
   356 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread* self) {
       
   357   if (self != _owner) {
   392   if (self != _owner) {
   358     return M_ILLEGAL_MONITOR_STATE;
   393     return M_ILLEGAL_MONITOR_STATE;
   359   }
   394   }
       
   395 
       
   396   int ret = M_OK;
   360 
   397 
   361   // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
   398   // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
   362   // The caller must be able to tolerate spurious returns from raw_wait().
   399   // The caller must be able to tolerate spurious returns from raw_wait().
   363   self->_ParkEvent->reset();
   400   self->_ParkEvent->reset();
   364   OrderAccess::fence();
   401   OrderAccess::fence();
   365 
   402 
   366   JavaThread* jt = NULL;
       
   367   // check interrupt event
       
   368   if (interruptible) {
       
   369     assert(self->is_Java_thread(), "Only JavaThreads can be interruptible");
       
   370     jt = (JavaThread*)self;
       
   371     if (jt->is_interrupted(true)) {
       
   372       return M_INTERRUPTED;
       
   373     }
       
   374   } else {
       
   375     assert(!self->is_Java_thread(), "JavaThreads must be interuptible");
       
   376   }
       
   377 
       
   378   intptr_t save = _recursions;
   403   intptr_t save = _recursions;
   379   _recursions = 0;
   404   _recursions = 0;
   380   _waiters++;
   405   _waiters++;
   381   if (self->is_Java_thread()) {
   406   ret = simple_wait(self, millis);
   382     guarantee(jt->thread_state() == _thread_blocked, "invariant");
       
   383     jt->set_suspend_equivalent();
       
   384   }
       
   385   int rv = simple_wait(self, millis);
       
   386   _recursions = save;
   407   _recursions = save;
   387   _waiters--;
   408   _waiters--;
   388 
   409 
   389   guarantee(self == _owner, "invariant");
   410   guarantee(self == _owner, "invariant");
       
   411 
   390   if (self->is_Java_thread()) {
   412   if (self->is_Java_thread()) {
       
   413     JavaThread* jt = (JavaThread*)self;
   391     for (;;) {
   414     for (;;) {
       
   415       jt->set_suspend_equivalent();
   392       if (!jt->handle_special_suspend_equivalent_condition()) {
   416       if (!jt->handle_special_suspend_equivalent_condition()) {
   393         break;
   417         break;
       
   418       } else {
       
   419         // We've been suspended whilst waiting and so we have to
       
   420         // relinquish the raw monitor until we are resumed. Of course
       
   421         // after reacquiring we have to re-check for suspension again.
       
   422         // Suspension requires we are _thread_blocked, and we also have to
       
   423         // recheck for being interrupted.
       
   424         simple_exit(jt);
       
   425         {
       
   426           ThreadInVMfromNative tivm(jt);
       
   427           {
       
   428             ThreadBlockInVM tbivm(jt);
       
   429             jt->java_suspend_self();
       
   430           }
       
   431           if (jt->is_interrupted(true)) {
       
   432             ret = M_INTERRUPTED;
       
   433           }
       
   434         }
       
   435         simple_enter(jt);
   394       }
   436       }
   395       simple_exit(jt);
       
   396       jt->java_suspend_self();
       
   397       simple_enter(jt);
       
   398       jt->set_suspend_equivalent();
       
   399     }
   437     }
   400     guarantee(jt == _owner, "invariant");
   438     guarantee(jt == _owner, "invariant");
   401   }
   439   } else {
   402 
   440     assert(ret != M_INTERRUPTED, "Only JavaThreads can be interrupted");
   403   if (interruptible && jt->is_interrupted(true)) {
   441   }
   404     return M_INTERRUPTED;
   442 
   405   }
   443   return ret;
   406 
       
   407   return M_OK;
       
   408 }
   444 }
   409 
   445 
   410 int JvmtiRawMonitor::raw_notify(Thread* self) {
   446 int JvmtiRawMonitor::raw_notify(Thread* self) {
   411   if (self != _owner) {
   447   if (self != _owner) {
   412     return M_ILLEGAL_MONITOR_STATE;
   448     return M_ILLEGAL_MONITOR_STATE;