< prev index next >

src/hotspot/share/prims/jvmtiRawMonitor.cpp

Print this page




 104   return value == JVMTI_RM_MAGIC;
 105 }
 106 
 107 // -------------------------------------------------------------------------
 108 // The JVMTI raw monitor subsystem is entirely distinct from normal
 109 // java-synchronization or jni-synchronization.  JVMTI raw monitors are not
 110 // associated with objects.  They can be implemented in any manner
 111 // that makes sense.  The original implementors decided to piggy-back
 112 // the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
 113 // Now we just use a simplified form of that ObjectMonitor code.
 114 //
 115 // Note that we use the single RawMonitor_lock to protect queue operations for
 116 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
 117 // is fairly rare, this is not of concern.  The RawMonitor_lock can not
 118 // be held indefinitely.  The critical sections must be short and bounded.
 119 //
 120 // -------------------------------------------------------------------------
 121 
 122 void JvmtiRawMonitor::simple_enter(Thread* self) {
 123   for (;;) {
 124     if (Atomic::replace_if_null(self, &_owner)) {
 125       return;
 126     }
 127 
 128     QNode node(self);
 129     self->_ParkEvent->reset();     // strictly optional
 130     node._t_state = QNode::TS_ENTER;
 131 
 132     RawMonitor_lock->lock_without_safepoint_check();
 133     node._next = _entry_list;
 134     _entry_list = &node;
 135     OrderAccess::fence();
 136     if (_owner == NULL && Atomic::replace_if_null(self, &_owner)) {
 137       _entry_list = node._next;
 138       RawMonitor_lock->unlock();
 139       return;
 140     }
 141     RawMonitor_lock->unlock();
 142     while (node._t_state == QNode::TS_ENTER) {
 143       self->_ParkEvent->park();
 144     }
 145   }
 146 }
 147 
 148 void JvmtiRawMonitor::simple_exit(Thread* self) {
 149   guarantee(_owner == self, "invariant");
 150   Atomic::release_store(&_owner, (Thread*)NULL);
 151   OrderAccess::fence();
 152   if (_entry_list == NULL) {
 153     return;
 154   }
 155 
 156   RawMonitor_lock->lock_without_safepoint_check();


 305     ev->unpark();
 306   }
 307   return;
 308 }
 309 
 310 // Any JavaThread will enter here with state _thread_blocked
 311 void JvmtiRawMonitor::raw_enter(Thread* self) {
 312   void* contended;
 313   JavaThread* jt = NULL;
 314   // don't enter raw monitor if thread is being externally suspended, it will
 315   // surprise the suspender if a "suspended" thread can still enter monitor
 316   if (self->is_Java_thread()) {
 317     jt = (JavaThread*)self;
 318     jt->SR_lock()->lock_without_safepoint_check();
 319     while (jt->is_external_suspend()) {
 320       jt->SR_lock()->unlock();
 321       jt->java_suspend_self();
 322       jt->SR_lock()->lock_without_safepoint_check();
 323     }
 324     // guarded by SR_lock to avoid racing with new external suspend requests.
 325     contended = Atomic::cmpxchg(jt, &_owner, (Thread*)NULL);
 326     jt->SR_lock()->unlock();
 327   } else {
 328     contended = Atomic::cmpxchg(self, &_owner, (Thread*)NULL);
 329   }
 330 
 331   if (contended == self) {
 332     _recursions++;
 333     return;
 334   }
 335 
 336   if (contended == NULL) {
 337     guarantee(_owner == self, "invariant");
 338     guarantee(_recursions == 0, "invariant");
 339     return;
 340   }
 341 
 342   self->set_current_pending_raw_monitor(this);
 343 
 344   if (!self->is_Java_thread()) {
 345     simple_enter(self);
 346   } else {
 347     guarantee(jt->thread_state() == _thread_blocked, "invariant");
 348     for (;;) {




 104   return value == JVMTI_RM_MAGIC;
 105 }
 106 
 107 // -------------------------------------------------------------------------
 108 // The JVMTI raw monitor subsystem is entirely distinct from normal
 109 // java-synchronization or jni-synchronization.  JVMTI raw monitors are not
 110 // associated with objects.  They can be implemented in any manner
 111 // that makes sense.  The original implementors decided to piggy-back
 112 // the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
 113 // Now we just use a simplified form of that ObjectMonitor code.
 114 //
 115 // Note that we use the single RawMonitor_lock to protect queue operations for
 116 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
 117 // is fairly rare, this is not of concern.  The RawMonitor_lock can not
 118 // be held indefinitely.  The critical sections must be short and bounded.
 119 //
 120 // -------------------------------------------------------------------------
 121 
 122 void JvmtiRawMonitor::simple_enter(Thread* self) {
 123   for (;;) {
 124     if (Atomic::replace_if_null(&_owner, self)) {
 125       return;
 126     }
 127 
 128     QNode node(self);
 129     self->_ParkEvent->reset();     // strictly optional
 130     node._t_state = QNode::TS_ENTER;
 131 
 132     RawMonitor_lock->lock_without_safepoint_check();
 133     node._next = _entry_list;
 134     _entry_list = &node;
 135     OrderAccess::fence();
 136     if (_owner == NULL && Atomic::replace_if_null(&_owner, self)) {
 137       _entry_list = node._next;
 138       RawMonitor_lock->unlock();
 139       return;
 140     }
 141     RawMonitor_lock->unlock();
 142     while (node._t_state == QNode::TS_ENTER) {
 143       self->_ParkEvent->park();
 144     }
 145   }
 146 }
 147 
 148 void JvmtiRawMonitor::simple_exit(Thread* self) {
 149   guarantee(_owner == self, "invariant");
 150   Atomic::release_store(&_owner, (Thread*)NULL);
 151   OrderAccess::fence();
 152   if (_entry_list == NULL) {
 153     return;
 154   }
 155 
 156   RawMonitor_lock->lock_without_safepoint_check();


 305     ev->unpark();
 306   }
 307   return;
 308 }
 309 
 310 // Any JavaThread will enter here with state _thread_blocked
 311 void JvmtiRawMonitor::raw_enter(Thread* self) {
 312   void* contended;
 313   JavaThread* jt = NULL;
 314   // don't enter raw monitor if thread is being externally suspended, it will
 315   // surprise the suspender if a "suspended" thread can still enter monitor
 316   if (self->is_Java_thread()) {
 317     jt = (JavaThread*)self;
 318     jt->SR_lock()->lock_without_safepoint_check();
 319     while (jt->is_external_suspend()) {
 320       jt->SR_lock()->unlock();
 321       jt->java_suspend_self();
 322       jt->SR_lock()->lock_without_safepoint_check();
 323     }
 324     // guarded by SR_lock to avoid racing with new external suspend requests.
 325     contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, jt);
 326     jt->SR_lock()->unlock();
 327   } else {
 328     contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, self);
 329   }
 330 
 331   if (contended == self) {
 332     _recursions++;
 333     return;
 334   }
 335 
 336   if (contended == NULL) {
 337     guarantee(_owner == self, "invariant");
 338     guarantee(_recursions == 0, "invariant");
 339     return;
 340   }
 341 
 342   self->set_current_pending_raw_monitor(this);
 343 
 344   if (!self->is_Java_thread()) {
 345     simple_enter(self);
 346   } else {
 347     guarantee(jt->thread_state() == _thread_blocked, "invariant");
 348     for (;;) {


< prev index next >