< prev index next >

src/hotspot/share/prims/jvmtiRawMonitor.cpp

Print this page




 110 // and move the resulting raw monitor implementation over to the JVMTI directories.
 111 // Ideally, the raw monitor implementation would be built on top of
 112 // park-unpark and nothing else.
 113 //
 114 // raw monitors are used mainly by JVMTI
 115 // The raw monitor implementation borrows the ObjectMonitor structure,
 116 // but the operators are degenerate and extremely simple.
 117 //
 118 // Mixed use of a single objectMonitor instance -- as both a raw monitor
 119 // and a normal java monitor -- is not permissible.
 120 //
 121 // Note that we use the single RawMonitor_lock to protect queue operations for
 122 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
 123 // is deprecated and rare, this is not of concern.  The RawMonitor_lock can not
 124 // be held indefinitely.  The critical sections must be short and bounded.
 125 //
 126 // -------------------------------------------------------------------------
 127 
 128 int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
 129   for (;;) {
 130     if (Atomic::cmpxchg((void*)Self, &_owner, (void*)NULL) == NULL) {
 131        return OS_OK ;
 132     }
 133 
 134     ObjectWaiter Node (Self) ;
 135     Self->_ParkEvent->reset() ;     // strictly optional
 136     Node.TState = ObjectWaiter::TS_ENTER ;
 137 
 138     RawMonitor_lock->lock_without_safepoint_check() ;
 139     Node._next  = _EntryList ;
 140     _EntryList  = &Node ;
 141     OrderAccess::fence() ;
 142     if (_owner == NULL && Atomic::cmpxchg((void*)Self, &_owner, (void*)NULL) == NULL) {
 143         _EntryList = Node._next ;
 144         RawMonitor_lock->unlock() ;
 145         return OS_OK ;
 146     }
 147     RawMonitor_lock->unlock() ;
 148     while (Node.TState == ObjectWaiter::TS_ENTER) {
 149        Self->_ParkEvent->park() ;
 150     }
 151   }
 152 }
 153 
 154 int JvmtiRawMonitor::SimpleExit (Thread * Self) {
 155   guarantee (_owner == Self, "invariant") ;
 156   OrderAccess::release_store(&_owner, (void*)NULL) ;
 157   OrderAccess::fence() ;
 158   if (_EntryList == NULL) return OS_OK ;
 159   ObjectWaiter * w ;
 160 
 161   RawMonitor_lock->lock_without_safepoint_check() ;
 162   w = _EntryList ;


 260   if (ev != NULL) ev->unpark();
 261   return OS_OK ;
 262 }
 263 
 264 // Any JavaThread will enter here with state _thread_blocked
 265 int JvmtiRawMonitor::raw_enter(TRAPS) {
 266   TEVENT (raw_enter) ;
 267   void * Contended ;
 268 
 269   // don't enter raw monitor if thread is being externally suspended, it will
 270   // surprise the suspender if a "suspended" thread can still enter monitor
 271   JavaThread * jt = (JavaThread *)THREAD;
 272   if (THREAD->is_Java_thread()) {
 273     jt->SR_lock()->lock_without_safepoint_check();
 274     while (jt->is_external_suspend()) {
 275       jt->SR_lock()->unlock();
 276       jt->java_suspend_self();
 277       jt->SR_lock()->lock_without_safepoint_check();
 278     }
 279     // guarded by SR_lock to avoid racing with new external suspend requests.
 280     Contended = Atomic::cmpxchg((void*)THREAD, &_owner, (void*)NULL);
 281     jt->SR_lock()->unlock();
 282   } else {
 283     Contended = Atomic::cmpxchg((void*)THREAD, &_owner, (void*)NULL);
 284   }
 285 
 286   if (Contended == THREAD) {
 287      _recursions ++ ;
 288      return OM_OK ;
 289   }
 290 
 291   if (Contended == NULL) {
 292      guarantee (_owner == THREAD, "invariant") ;
 293      guarantee (_recursions == 0, "invariant") ;
 294      return OM_OK ;
 295   }
 296 
 297   THREAD->set_current_pending_monitor(this);
 298 
 299   if (!THREAD->is_Java_thread()) {
 300      // No other non-Java threads besides VM thread would acquire
 301      // a raw monitor.
 302      assert(THREAD->is_VM_thread(), "must be VM thread");
 303      SimpleEnter (THREAD) ;




 110 // and move the resulting raw monitor implementation over to the JVMTI directories.
 111 // Ideally, the raw monitor implementation would be built on top of
 112 // park-unpark and nothing else.
 113 //
 114 // raw monitors are used mainly by JVMTI
 115 // The raw monitor implementation borrows the ObjectMonitor structure,
 116 // but the operators are degenerate and extremely simple.
 117 //
 118 // Mixed use of a single objectMonitor instance -- as both a raw monitor
 119 // and a normal java monitor -- is not permissible.
 120 //
 121 // Note that we use the single RawMonitor_lock to protect queue operations for
 122 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
 123 // is deprecated and rare, this is not of concern.  The RawMonitor_lock can not
 124 // be held indefinitely.  The critical sections must be short and bounded.
 125 //
 126 // -------------------------------------------------------------------------
 127 
 128 int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
 129   for (;;) {
 130     if (Atomic::cmpxchg(Self, &_owner, (void*)NULL) == NULL) {
 131        return OS_OK ;
 132     }
 133 
 134     ObjectWaiter Node (Self) ;
 135     Self->_ParkEvent->reset() ;     // strictly optional
 136     Node.TState = ObjectWaiter::TS_ENTER ;
 137 
 138     RawMonitor_lock->lock_without_safepoint_check() ;
 139     Node._next  = _EntryList ;
 140     _EntryList  = &Node ;
 141     OrderAccess::fence() ;
 142     if (_owner == NULL && Atomic::cmpxchg(Self, &_owner, (void*)NULL) == NULL) {
 143         _EntryList = Node._next ;
 144         RawMonitor_lock->unlock() ;
 145         return OS_OK ;
 146     }
 147     RawMonitor_lock->unlock() ;
 148     while (Node.TState == ObjectWaiter::TS_ENTER) {
 149        Self->_ParkEvent->park() ;
 150     }
 151   }
 152 }
 153 
 154 int JvmtiRawMonitor::SimpleExit (Thread * Self) {
 155   guarantee (_owner == Self, "invariant") ;
 156   OrderAccess::release_store(&_owner, (void*)NULL) ;
 157   OrderAccess::fence() ;
 158   if (_EntryList == NULL) return OS_OK ;
 159   ObjectWaiter * w ;
 160 
 161   RawMonitor_lock->lock_without_safepoint_check() ;
 162   w = _EntryList ;


 260   if (ev != NULL) ev->unpark();
 261   return OS_OK ;
 262 }
 263 
 264 // Any JavaThread will enter here with state _thread_blocked
 265 int JvmtiRawMonitor::raw_enter(TRAPS) {
 266   TEVENT (raw_enter) ;
 267   void * Contended ;
 268 
 269   // don't enter raw monitor if thread is being externally suspended, it will
 270   // surprise the suspender if a "suspended" thread can still enter monitor
 271   JavaThread * jt = (JavaThread *)THREAD;
 272   if (THREAD->is_Java_thread()) {
 273     jt->SR_lock()->lock_without_safepoint_check();
 274     while (jt->is_external_suspend()) {
 275       jt->SR_lock()->unlock();
 276       jt->java_suspend_self();
 277       jt->SR_lock()->lock_without_safepoint_check();
 278     }
 279     // guarded by SR_lock to avoid racing with new external suspend requests.
 280     Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
 281     jt->SR_lock()->unlock();
 282   } else {
 283     Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
 284   }
 285 
 286   if (Contended == THREAD) {
 287      _recursions ++ ;
 288      return OM_OK ;
 289   }
 290 
 291   if (Contended == NULL) {
 292      guarantee (_owner == THREAD, "invariant") ;
 293      guarantee (_recursions == 0, "invariant") ;
 294      return OM_OK ;
 295   }
 296 
 297   THREAD->set_current_pending_monitor(this);
 298 
 299   if (!THREAD->is_Java_thread()) {
 300      // No other non-Java threads besides VM thread would acquire
 301      // a raw monitor.
 302      assert(THREAD->is_VM_thread(), "must be VM thread");
 303      SimpleEnter (THREAD) ;


< prev index next >