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 (;;) { |