src/hotspot/share/prims/jvmtiRawMonitor.cpp
changeset 58488 165b193b30dd
parent 58196 cea6839598e8
child 58509 7b41c88f8432
equal deleted inserted replaced
58487:43f63f904bbc 58488:165b193b30dd
    28 #include "runtime/atomic.hpp"
    28 #include "runtime/atomic.hpp"
    29 #include "runtime/interfaceSupport.inline.hpp"
    29 #include "runtime/interfaceSupport.inline.hpp"
    30 #include "runtime/orderAccess.hpp"
    30 #include "runtime/orderAccess.hpp"
    31 #include "runtime/thread.inline.hpp"
    31 #include "runtime/thread.inline.hpp"
    32 
    32 
    33 GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
    33 JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
       
    34                                                 _event(thread->_ParkEvent),
       
    35                                                 _notified(0), TState(TS_RUN) {
       
    36 }
       
    37 
       
    38 GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors =
       
    39   new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
    34 
    40 
    35 void JvmtiPendingMonitors::transition_raw_monitors() {
    41 void JvmtiPendingMonitors::transition_raw_monitors() {
    36   assert((Threads::number_of_threads()==1),
    42   assert((Threads::number_of_threads()==1),
    37          "Java thread has not created yet or more than one java thread \
    43          "Java thread has not been created yet or more than one java thread \
    38 is running. Raw monitor transition will not work");
    44 is running. Raw monitor transition will not work");
    39   JavaThread *current_java_thread = JavaThread::current();
    45   JavaThread *current_java_thread = JavaThread::current();
    40   assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
    46   assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
    41   {
    47   for(int i=0; i< count(); i++) {
    42     ThreadBlockInVM __tbivm(current_java_thread);
    48     JvmtiRawMonitor *rmonitor = monitors()->at(i);
    43     for(int i=0; i< count(); i++) {
    49     rmonitor->raw_enter(current_java_thread);
    44       JvmtiRawMonitor *rmonitor = monitors()->at(i);
       
    45       int r = rmonitor->raw_enter(current_java_thread);
       
    46       assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
       
    47     }
       
    48   }
    50   }
    49   // pending monitors are converted to real monitor so delete them all.
    51   // pending monitors are converted to real monitor so delete them all.
    50   dispose();
    52   dispose();
    51 }
    53 }
    52 
    54 
    53 //
    55 //
    54 // class JvmtiRawMonitor
    56 // class JvmtiRawMonitor
    55 //
    57 //
    56 
    58 
    57 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
    59 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) : _owner(NULL),
       
    60                                                      _recursions(0),
       
    61                                                      _EntryList(NULL),
       
    62                                                      _WaitSet(NULL),
       
    63                                                      _waiters(0),
       
    64                                                      _magic(JVMTI_RM_MAGIC),
       
    65                                                      _name(NULL) {
    58 #ifdef ASSERT
    66 #ifdef ASSERT
    59   _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
    67   _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
    60 #else
       
    61   _name = NULL;
       
    62 #endif
    68 #endif
    63   _magic = JVMTI_RM_MAGIC;
       
    64 }
    69 }
    65 
    70 
    66 JvmtiRawMonitor::~JvmtiRawMonitor() {
    71 JvmtiRawMonitor::~JvmtiRawMonitor() {
    67 #ifdef ASSERT
    72 #ifdef ASSERT
    68   FreeHeap(_name);
    73   FreeHeap(_name);
    98 
   103 
    99   return value == JVMTI_RM_MAGIC;
   104   return value == JVMTI_RM_MAGIC;
   100 }
   105 }
   101 
   106 
   102 // -------------------------------------------------------------------------
   107 // -------------------------------------------------------------------------
   103 // The raw monitor subsystem is entirely distinct from normal
   108 // The JVMTI raw monitor subsystem is entirely distinct from normal
   104 // java-synchronization or jni-synchronization.  raw monitors are not
   109 // java-synchronization or jni-synchronization.  JVMTI raw monitors are not
   105 // associated with objects.  They can be implemented in any manner
   110 // associated with objects.  They can be implemented in any manner
   106 // that makes sense.  The original implementors decided to piggy-back
   111 // that makes sense.  The original implementors decided to piggy-back
   107 // the raw-monitor implementation on the existing Java objectMonitor mechanism.
   112 // the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
   108 // This flaw needs to fixed.  We should reimplement raw monitors as sui-generis.
   113 // Now we just use a simplified form of that ObjectMonitor code.
   109 // Specifically, we should not implement raw monitors via java monitors.
       
   110 // Time permitting, we should disentangle and deconvolve the two implementations
       
   111 // and move the resulting raw monitor implementation over to the JVMTI directories.
       
   112 // Ideally, the raw monitor implementation would be built on top of
       
   113 // park-unpark and nothing else.
       
   114 //
       
   115 // raw monitors are used mainly by JVMTI
       
   116 // The raw monitor implementation borrows the ObjectMonitor structure,
       
   117 // but the operators are degenerate and extremely simple.
       
   118 //
       
   119 // Mixed use of a single objectMonitor instance -- as both a raw monitor
       
   120 // and a normal java monitor -- is not permissible.
       
   121 //
   114 //
   122 // Note that we use the single RawMonitor_lock to protect queue operations for
   115 // Note that we use the single RawMonitor_lock to protect queue operations for
   123 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
   116 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
   124 // is deprecated and rare, this is not of concern.  The RawMonitor_lock can not
   117 // is fairly rare, this is not of concern.  The RawMonitor_lock can not
   125 // be held indefinitely.  The critical sections must be short and bounded.
   118 // be held indefinitely.  The critical sections must be short and bounded.
   126 //
   119 //
   127 // -------------------------------------------------------------------------
   120 // -------------------------------------------------------------------------
   128 
   121 
   129 int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
   122 void JvmtiRawMonitor::SimpleEnter (Thread * Self) {
   130   for (;;) {
   123   for (;;) {
   131     if (Atomic::replace_if_null(Self, &_owner)) {
   124     if (Atomic::replace_if_null(Self, &_owner)) {
   132        return OS_OK ;
   125        return ;
   133     }
   126     }
   134 
   127 
   135     ObjectWaiter Node (Self) ;
   128     QNode Node (Self) ;
   136     Self->_ParkEvent->reset() ;     // strictly optional
   129     Self->_ParkEvent->reset() ;     // strictly optional
   137     Node.TState = ObjectWaiter::TS_ENTER ;
   130     Node.TState = QNode::TS_ENTER ;
   138 
   131 
   139     RawMonitor_lock->lock_without_safepoint_check() ;
   132     RawMonitor_lock->lock_without_safepoint_check() ;
   140     Node._next  = _EntryList ;
   133     Node._next  = _EntryList ;
   141     _EntryList  = &Node ;
   134     _EntryList  = &Node ;
   142     OrderAccess::fence() ;
   135     OrderAccess::fence() ;
   143     if (_owner == NULL && Atomic::replace_if_null(Self, &_owner)) {
   136     if (_owner == NULL && Atomic::replace_if_null(Self, &_owner)) {
   144         _EntryList = Node._next ;
   137         _EntryList = Node._next ;
   145         RawMonitor_lock->unlock() ;
   138         RawMonitor_lock->unlock() ;
   146         return OS_OK ;
   139         return ;
   147     }
   140     }
   148     RawMonitor_lock->unlock() ;
   141     RawMonitor_lock->unlock() ;
   149     while (Node.TState == ObjectWaiter::TS_ENTER) {
   142     while (Node.TState == QNode::TS_ENTER) {
   150        Self->_ParkEvent->park() ;
   143        Self->_ParkEvent->park() ;
   151     }
   144     }
   152   }
   145   }
   153 }
   146 }
   154 
   147 
   155 int JvmtiRawMonitor::SimpleExit (Thread * Self) {
   148 void JvmtiRawMonitor::SimpleExit (Thread * Self) {
   156   guarantee (_owner == Self, "invariant") ;
   149   guarantee (_owner == Self, "invariant") ;
   157   OrderAccess::release_store(&_owner, (void*)NULL) ;
   150   OrderAccess::release_store(&_owner, (Thread*)NULL) ;
   158   OrderAccess::fence() ;
   151   OrderAccess::fence() ;
   159   if (_EntryList == NULL) return OS_OK ;
   152   if (_EntryList == NULL) return ;
   160   ObjectWaiter * w ;
   153   QNode * w ;
   161 
   154 
   162   RawMonitor_lock->lock_without_safepoint_check() ;
   155   RawMonitor_lock->lock_without_safepoint_check() ;
   163   w = _EntryList ;
   156   w = _EntryList ;
   164   if (w != NULL) {
   157   if (w != NULL) {
   165       _EntryList = w->_next ;
   158       _EntryList = w->_next ;
   166   }
   159   }
   167   RawMonitor_lock->unlock() ;
   160   RawMonitor_lock->unlock() ;
   168   if (w != NULL) {
   161   if (w != NULL) {
   169       guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
   162       guarantee (w ->TState == QNode::TS_ENTER, "invariant") ;
   170       // Once we set TState to TS_RUN the waiting thread can complete
   163       // Once we set TState to TS_RUN the waiting thread can complete
   171       // SimpleEnter and 'w' is pointing into random stack space. So we have
   164       // SimpleEnter and 'w' is pointing into random stack space. So we have
   172       // to ensure we extract the ParkEvent (which is in type-stable memory)
   165       // to ensure we extract the ParkEvent (which is in type-stable memory)
   173       // before we set the state, and then don't access 'w'.
   166       // before we set the state, and then don't access 'w'.
   174       ParkEvent * ev = w->_event ;
   167       ParkEvent * ev = w->_event ;
   175       OrderAccess::loadstore();
   168       OrderAccess::loadstore();
   176       w->TState = ObjectWaiter::TS_RUN ;
   169       w->TState = QNode::TS_RUN ;
   177       OrderAccess::fence() ;
   170       OrderAccess::fence() ;
   178       ev->unpark() ;
   171       ev->unpark() ;
   179   }
   172   }
   180   return OS_OK ;
   173   return ;
   181 }
   174 }
   182 
   175 
   183 int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
   176 int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
   184   guarantee (_owner == Self  , "invariant") ;
   177   guarantee (_owner == Self  , "invariant") ;
   185   guarantee (_recursions == 0, "invariant") ;
   178   guarantee (_recursions == 0, "invariant") ;
   186 
   179 
   187   ObjectWaiter Node (Self) ;
   180   QNode Node (Self) ;
   188   Node._notified = 0 ;
   181   Node._notified = 0 ;
   189   Node.TState    = ObjectWaiter::TS_WAIT ;
   182   Node.TState    = QNode::TS_WAIT ;
   190 
   183 
   191   RawMonitor_lock->lock_without_safepoint_check() ;
   184   RawMonitor_lock->lock_without_safepoint_check() ;
   192   Node._next     = _WaitSet ;
   185   Node._next     = _WaitSet ;
   193   _WaitSet       = &Node ;
   186   _WaitSet       = &Node ;
   194   RawMonitor_lock->unlock() ;
   187   RawMonitor_lock->unlock() ;
   206   // If thread still resides on the waitset then unlink it.
   199   // If thread still resides on the waitset then unlink it.
   207   // Double-checked locking -- the usage is safe in this context
   200   // Double-checked locking -- the usage is safe in this context
   208   // as TState is volatile and the lock-unlock operators are
   201   // as TState is volatile and the lock-unlock operators are
   209   // serializing (barrier-equivalent).
   202   // serializing (barrier-equivalent).
   210 
   203 
   211   if (Node.TState == ObjectWaiter::TS_WAIT) {
   204   if (Node.TState == QNode::TS_WAIT) {
   212     RawMonitor_lock->lock_without_safepoint_check() ;
   205     RawMonitor_lock->lock_without_safepoint_check() ;
   213     if (Node.TState == ObjectWaiter::TS_WAIT) {
   206     if (Node.TState == QNode::TS_WAIT) {
   214       // Simple O(n) unlink, but performance isn't critical here.
   207       // Simple O(n) unlink, but performance isn't critical here.
   215       ObjectWaiter * p ;
   208       QNode * p ;
   216       ObjectWaiter * q = NULL ;
   209       QNode * q = NULL ;
   217       for (p = _WaitSet ; p != &Node; p = p->_next) {
   210       for (p = _WaitSet ; p != &Node; p = p->_next) {
   218          q = p ;
   211          q = p ;
   219       }
   212       }
   220       guarantee (p == &Node, "invariant") ;
   213       guarantee (p == &Node, "invariant") ;
   221       if (q == NULL) {
   214       if (q == NULL) {
   223         _WaitSet = p->_next ;
   216         _WaitSet = p->_next ;
   224       } else {
   217       } else {
   225         guarantee (p == q->_next, "invariant") ;
   218         guarantee (p == q->_next, "invariant") ;
   226         q->_next = p->_next ;
   219         q->_next = p->_next ;
   227       }
   220       }
   228       Node.TState = ObjectWaiter::TS_RUN ;
   221       Node.TState = QNode::TS_RUN ;
   229     }
   222     }
   230     RawMonitor_lock->unlock() ;
   223     RawMonitor_lock->unlock() ;
   231   }
   224   }
   232 
   225 
   233   guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
   226   guarantee (Node.TState == QNode::TS_RUN, "invariant") ;
   234   SimpleEnter (Self) ;
   227   SimpleEnter (Self) ;
   235 
   228 
   236   guarantee (_owner == Self, "invariant") ;
   229   guarantee (_owner == Self, "invariant") ;
   237   guarantee (_recursions == 0, "invariant") ;
   230   guarantee (_recursions == 0, "invariant") ;
   238   return ret ;
   231   return ret ;
   239 }
   232 }
   240 
   233 
   241 int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
   234 void JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
   242   guarantee (_owner == Self, "invariant") ;
   235   guarantee (_owner == Self, "invariant") ;
   243   if (_WaitSet == NULL) return OS_OK ;
   236   if (_WaitSet == NULL) return ;
   244 
   237 
   245   // We have two options:
   238   // We have two options:
   246   // A. Transfer the threads from the WaitSet to the EntryList
   239   // A. Transfer the threads from the WaitSet to the EntryList
   247   // B. Remove the thread from the WaitSet and unpark() it.
   240   // B. Remove the thread from the WaitSet and unpark() it.
   248   //
   241   //
   250   // context switching.  In particular (B) induces lots of contention.
   243   // context switching.  In particular (B) induces lots of contention.
   251 
   244 
   252   ParkEvent * ev = NULL ;       // consider using a small auto array ...
   245   ParkEvent * ev = NULL ;       // consider using a small auto array ...
   253   RawMonitor_lock->lock_without_safepoint_check() ;
   246   RawMonitor_lock->lock_without_safepoint_check() ;
   254   for (;;) {
   247   for (;;) {
   255       ObjectWaiter * w = _WaitSet ;
   248       QNode * w = _WaitSet ;
   256       if (w == NULL) break ;
   249       if (w == NULL) break ;
   257       _WaitSet = w->_next ;
   250       _WaitSet = w->_next ;
   258       if (ev != NULL) { ev->unpark(); ev = NULL; }
   251       if (ev != NULL) { ev->unpark(); ev = NULL; }
   259       ev = w->_event ;
   252       ev = w->_event ;
   260       OrderAccess::loadstore() ;
   253       OrderAccess::loadstore() ;
   261       w->TState = ObjectWaiter::TS_RUN ;
   254       w->TState = QNode::TS_RUN ;
   262       OrderAccess::storeload();
   255       OrderAccess::storeload();
   263       if (!All) break ;
   256       if (!All) break ;
   264   }
   257   }
   265   RawMonitor_lock->unlock() ;
   258   RawMonitor_lock->unlock() ;
   266   if (ev != NULL) ev->unpark();
   259   if (ev != NULL) ev->unpark();
   267   return OS_OK ;
   260   return ;
   268 }
   261 }
   269 
   262 
   270 // Any JavaThread will enter here with state _thread_blocked
   263 // Any JavaThread will enter here with state _thread_blocked
   271 int JvmtiRawMonitor::raw_enter(TRAPS) {
   264 void JvmtiRawMonitor::raw_enter(Thread * Self) {
   272   void * Contended ;
   265   void * Contended ;
   273 
   266   JavaThread * jt = NULL;
   274   // don't enter raw monitor if thread is being externally suspended, it will
   267   // don't enter raw monitor if thread is being externally suspended, it will
   275   // surprise the suspender if a "suspended" thread can still enter monitor
   268   // surprise the suspender if a "suspended" thread can still enter monitor
   276   JavaThread * jt = (JavaThread *)THREAD;
   269   if (Self->is_Java_thread()) {
   277   if (THREAD->is_Java_thread()) {
   270     jt = (JavaThread*) Self;
   278     jt->SR_lock()->lock_without_safepoint_check();
   271     jt->SR_lock()->lock_without_safepoint_check();
   279     while (jt->is_external_suspend()) {
   272     while (jt->is_external_suspend()) {
   280       jt->SR_lock()->unlock();
   273       jt->SR_lock()->unlock();
   281       jt->java_suspend_self();
   274       jt->java_suspend_self();
   282       jt->SR_lock()->lock_without_safepoint_check();
   275       jt->SR_lock()->lock_without_safepoint_check();
   283     }
   276     }
   284     // guarded by SR_lock to avoid racing with new external suspend requests.
   277     // guarded by SR_lock to avoid racing with new external suspend requests.
   285     Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
   278     Contended = Atomic::cmpxchg(jt, &_owner, (Thread*)NULL);
   286     jt->SR_lock()->unlock();
   279     jt->SR_lock()->unlock();
   287   } else {
   280   } else {
   288     Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
   281     Contended = Atomic::cmpxchg(Self, &_owner, (Thread*)NULL);
   289   }
   282   }
   290 
   283 
   291   if (Contended == THREAD) {
   284   if (Contended == Self) {
   292      _recursions ++ ;
   285      _recursions ++ ;
   293      return OM_OK ;
   286      return ;
   294   }
   287   }
   295 
   288 
   296   if (Contended == NULL) {
   289   if (Contended == NULL) {
   297      guarantee (_owner == THREAD, "invariant") ;
   290      guarantee (_owner == Self, "invariant") ;
   298      guarantee (_recursions == 0, "invariant") ;
   291      guarantee (_recursions == 0, "invariant") ;
   299      return OM_OK ;
   292      return ;
   300   }
   293   }
   301 
   294 
   302   THREAD->set_current_pending_monitor(this);
   295   Self->set_current_pending_raw_monitor(this);
   303 
   296 
   304   if (!THREAD->is_Java_thread()) {
   297   if (!Self->is_Java_thread()) {
   305      // No other non-Java threads besides VM thread would acquire
   298      SimpleEnter (Self) ;
   306      // a raw monitor.
   299   } else {
   307      assert(THREAD->is_VM_thread(), "must be VM thread");
   300     guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
   308      SimpleEnter (THREAD) ;
   301     for (;;) {
   309    } else {
   302       jt->set_suspend_equivalent();
   310      guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
   303       // cleared by handle_special_suspend_equivalent_condition() or
   311      for (;;) {
   304       // java_suspend_self()
   312        jt->set_suspend_equivalent();
   305       SimpleEnter (jt) ;
   313        // cleared by handle_special_suspend_equivalent_condition() or
   306 
   314        // java_suspend_self()
   307       // were we externally suspended while we were waiting?
   315        SimpleEnter (THREAD) ;
   308       if (!jt->handle_special_suspend_equivalent_condition()) break ;
   316 
   309 
   317        // were we externally suspended while we were waiting?
   310       // This thread was externally suspended
   318        if (!jt->handle_special_suspend_equivalent_condition()) break ;
   311       // We have reentered the contended monitor, but while we were
   319 
   312       // waiting another thread suspended us. We don't want to reenter
   320        // This thread was externally suspended
   313       // the monitor while suspended because that would surprise the
   321        //
   314       // thread that suspended us.
   322        // This logic isn't needed for JVMTI raw monitors,
   315       //
   323        // but doesn't hurt just in case the suspend rules change. This
   316       // Drop the lock
   324            // logic is needed for the JvmtiRawMonitor.wait() reentry phase.
   317       SimpleExit (jt) ;
   325            // We have reentered the contended monitor, but while we were
   318 
   326            // waiting another thread suspended us. We don't want to reenter
   319       jt->java_suspend_self();
   327            // the monitor while suspended because that would surprise the
   320     }
   328            // thread that suspended us.
   321   }
   329            //
   322 
   330            // Drop the lock -
   323   Self->set_current_pending_raw_monitor(NULL);
   331        SimpleExit (THREAD) ;
   324 
   332 
   325   guarantee (_owner == Self, "invariant") ;
   333            jt->java_suspend_self();
       
   334          }
       
   335 
       
   336      assert(_owner == THREAD, "Fatal error with monitor owner!");
       
   337      assert(_recursions == 0, "Fatal error with monitor recursions!");
       
   338   }
       
   339 
       
   340   THREAD->set_current_pending_monitor(NULL);
       
   341   guarantee (_recursions == 0, "invariant") ;
   326   guarantee (_recursions == 0, "invariant") ;
   342   return OM_OK;
   327 }
   343 }
   328 
   344 
   329 int JvmtiRawMonitor::raw_exit(Thread * Self) {
   345 // Used mainly for JVMTI raw monitor implementation
   330   if (Self != _owner) {
   346 // Also used for JvmtiRawMonitor::wait().
   331     return M_ILLEGAL_MONITOR_STATE;
   347 int JvmtiRawMonitor::raw_exit(TRAPS) {
       
   348   if (THREAD != _owner) {
       
   349     return OM_ILLEGAL_MONITOR_STATE;
       
   350   }
   332   }
   351   if (_recursions > 0) {
   333   if (_recursions > 0) {
   352     --_recursions ;
   334     --_recursions ;
   353     return OM_OK ;
   335   } else {
   354   }
   336     SimpleExit (Self) ;
   355 
   337   }
   356   void * List = _EntryList ;
   338 
   357   SimpleExit (THREAD) ;
   339   return M_OK;
   358 
   340 }
   359   return OM_OK;
   341 
   360 }
       
   361 
       
   362 // Used for JVMTI raw monitor implementation.
       
   363 // All JavaThreads will enter here with state _thread_blocked
   342 // All JavaThreads will enter here with state _thread_blocked
   364 
   343 
   365 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
   344 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread * Self) {
   366   if (THREAD != _owner) {
   345   if (Self != _owner) {
   367     return OM_ILLEGAL_MONITOR_STATE;
   346     return M_ILLEGAL_MONITOR_STATE;
   368   }
   347   }
   369 
   348 
   370   // To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
   349   // To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
   371   // The caller must be able to tolerate spurious returns from raw_wait().
   350   // The caller must be able to tolerate spurious returns from raw_wait().
   372   THREAD->_ParkEvent->reset() ;
   351   Self->_ParkEvent->reset() ;
   373   OrderAccess::fence() ;
   352   OrderAccess::fence() ;
   374 
   353 
       
   354   JavaThread * jt = NULL;
   375   // check interrupt event
   355   // check interrupt event
   376   if (interruptible) {
   356   if (interruptible) {
   377     assert(THREAD->is_Java_thread(), "Only JavaThreads can be interruptible");
   357     assert(Self->is_Java_thread(), "Only JavaThreads can be interruptible");
   378     JavaThread* jt = (JavaThread*) THREAD;
   358     jt = (JavaThread*) Self;
   379     if (jt->is_interrupted(true)) {
   359     if (jt->is_interrupted(true)) {
   380       return OM_INTERRUPTED;
   360       return M_INTERRUPTED;
   381     }
   361     }
       
   362   } else {
       
   363     assert(!Self->is_Java_thread(), "JavaThreads must be interuptible");
   382   }
   364   }
   383 
   365 
   384   intptr_t save = _recursions ;
   366   intptr_t save = _recursions ;
   385   _recursions = 0 ;
   367   _recursions = 0 ;
   386   _waiters ++ ;
   368   _waiters ++ ;
   387   if (THREAD->is_Java_thread()) {
   369   if (Self->is_Java_thread()) {
   388     guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
   370     guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
   389     ((JavaThread *)THREAD)->set_suspend_equivalent();
   371     jt->set_suspend_equivalent();
   390   }
   372   }
   391   int rv = SimpleWait (THREAD, millis) ;
   373   int rv = SimpleWait (Self, millis) ;
   392   _recursions = save ;
   374   _recursions = save ;
   393   _waiters -- ;
   375   _waiters -- ;
   394 
   376 
   395   guarantee (THREAD == _owner, "invariant") ;
   377   guarantee (Self == _owner, "invariant") ;
   396   if (THREAD->is_Java_thread()) {
   378   if (Self->is_Java_thread()) {
   397      JavaThread * jSelf = (JavaThread *) THREAD ;
       
   398      for (;;) {
   379      for (;;) {
   399         if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
   380         if (!jt->handle_special_suspend_equivalent_condition()) break ;
   400         SimpleExit (THREAD) ;
   381         SimpleExit (jt) ;
   401         jSelf->java_suspend_self();
   382         jt->java_suspend_self();
   402         SimpleEnter (THREAD) ;
   383         SimpleEnter (jt) ;
   403         jSelf->set_suspend_equivalent() ;
   384         jt->set_suspend_equivalent() ;
   404      }
   385      }
   405   }
   386      guarantee (jt == _owner, "invariant") ;
   406   guarantee (THREAD == _owner, "invariant") ;
   387   }
   407 
   388 
   408   if (interruptible) {
   389   if (interruptible && jt->is_interrupted(true)) {
   409     JavaThread* jt = (JavaThread*) THREAD;
   390     return M_INTERRUPTED;
   410     if (jt->is_interrupted(true)) {
   391   }
   411       return OM_INTERRUPTED;
   392 
   412     }
   393   return M_OK ;
   413   }
   394 }
   414   return OM_OK ;
   395 
   415 }
   396 int JvmtiRawMonitor::raw_notify(Thread * Self) {
   416 
   397   if (Self != _owner) {
   417 int JvmtiRawMonitor::raw_notify(TRAPS) {
   398     return M_ILLEGAL_MONITOR_STATE;
   418   if (THREAD != _owner) {
   399   }
   419     return OM_ILLEGAL_MONITOR_STATE;
   400   SimpleNotify (Self, false) ;
   420   }
   401   return M_OK;
   421   SimpleNotify (THREAD, false) ;
   402 }
   422   return OM_OK;
   403 
   423 }
   404 int JvmtiRawMonitor::raw_notifyAll(Thread * Self) {
   424 
   405   if (Self != _owner) {
   425 int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
   406     return M_ILLEGAL_MONITOR_STATE;
   426   if (THREAD != _owner) {
   407   }
   427     return OM_ILLEGAL_MONITOR_STATE;
   408   SimpleNotify (Self, true) ;
   428   }
   409   return M_OK;
   429   SimpleNotify (THREAD, true) ;
   410 }
   430   return OM_OK;
       
   431 }