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