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