1188 event->commit();
1189 }
1190
1191 // -----------------------------------------------------------------------------
1192 // Wait/Notify/NotifyAll
1193 //
1194 // Note: a subset of changes to ObjectMonitor::wait()
1195 // will need to be replicated in complete_exit
1196 void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
1197 Thread * const Self = THREAD;
1198 assert(Self->is_Java_thread(), "Must be Java thread!");
1199 JavaThread *jt = (JavaThread *)THREAD;
1200
1201 assert(InitDone, "Unexpectedly not initialized");
1202
1203 CHECK_OWNER(); // Throws IMSE if not owner.
1204
1205 EventJavaMonitorWait event;
1206
1207 // check for a pending interrupt
1208 if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
1209 // post monitor waited event. Note that this is past-tense, we are done waiting.
1210 if (JvmtiExport::should_post_monitor_waited()) {
1211 // Note: 'false' parameter is passed here because the
1212 // wait was not timed out due to thread interrupt.
1213 JvmtiExport::post_monitor_waited(jt, this, false);
1214
1215 // In this short circuit of the monitor wait protocol, the
1216 // current thread never drops ownership of the monitor and
1217 // never gets added to the wait queue so the current thread
1218 // cannot be made the successor. This means that the
1219 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally
1220 // consume an unpark() meant for the ParkEvent associated with
1221 // this ObjectMonitor.
1222 }
1223 if (event.should_commit()) {
1224 post_monitor_wait_event(&event, this, 0, millis, false);
1225 }
1226 THROW(vmSymbols::java_lang_InterruptedException());
1227 return;
1228 }
1258 exit(true, Self); // exit the monitor
1259 guarantee(_owner != Self, "invariant");
1260
1261 // The thread is on the WaitSet list - now park() it.
1262 // On MP systems it's conceivable that a brief spin before we park
1263 // could be profitable.
1264 //
1265 // TODO-FIXME: change the following logic to a loop of the form
1266 // while (!timeout && !interrupted && _notified == 0) park()
1267
1268 int ret = OS_OK;
1269 int WasNotified = 0;
1270 { // State transition wrappers
1271 OSThread* osthread = Self->osthread();
1272 OSThreadWaitState osts(osthread, true);
1273 {
1274 ThreadBlockInVM tbivm(jt);
1275 // Thread is in thread_blocked state and oop access is unsafe.
1276 jt->set_suspend_equivalent();
1277
1278 if (interruptible && (Thread::is_interrupted(THREAD, false) || HAS_PENDING_EXCEPTION)) {
1279 // Intentionally empty
1280 } else if (node._notified == 0) {
1281 if (millis <= 0) {
1282 Self->_ParkEvent->park();
1283 } else {
1284 ret = Self->_ParkEvent->park(millis);
1285 }
1286 }
1287
1288 // were we externally suspended while we were waiting?
1289 if (ExitSuspendEquivalent (jt)) {
1290 // TODO-FIXME: add -- if succ == Self then succ = null.
1291 jt->java_suspend_self();
1292 }
1293
1294 } // Exit thread safepoint: transition _thread_blocked -> _thread_in_vm
1295
1296 // Node may be on the WaitSet, the EntryList (or cxq), or in transition
1297 // from the WaitSet to the EntryList.
1298 // See if we need to remove Node from the WaitSet.
1384 guarantee(node.TState == ObjectWaiter::TS_RUN, "invariant");
1385 assert(_owner == Self, "invariant");
1386 assert(_succ != Self, "invariant");
1387 } // OSThreadWaitState()
1388
1389 jt->set_current_waiting_monitor(NULL);
1390
1391 guarantee(_recursions == 0, "invariant");
1392 _recursions = save; // restore the old recursion count
1393 _waiters--; // decrement the number of waiters
1394
1395 // Verify a few postconditions
1396 assert(_owner == Self, "invariant");
1397 assert(_succ != Self, "invariant");
1398 assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
1399
1400 // check if the notification happened
1401 if (!WasNotified) {
1402 // no, it could be timeout or Thread.interrupt() or both
1403 // check for interrupt event, otherwise it is timeout
1404 if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
1405 THROW(vmSymbols::java_lang_InterruptedException());
1406 }
1407 }
1408
1409 // NOTE: Spurious wake up will be consider as timeout.
1410 // Monitor notify has precedence over thread interrupt.
1411 }
1412
1413
1414 // Consider:
1415 // If the lock is cool (cxq == null && succ == null) and we're on an MP system
1416 // then instead of transferring a thread from the WaitSet to the EntryList
1417 // we might just dequeue a thread from the WaitSet and directly unpark() it.
1418
1419 void ObjectMonitor::INotify(Thread * Self) {
1420 Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
1421 ObjectWaiter * iterator = DequeueWaiter();
1422 if (iterator != NULL) {
1423 guarantee(iterator->TState == ObjectWaiter::TS_WAIT, "invariant");
1424 guarantee(iterator->_notified == 0, "invariant");
|
1188 event->commit();
1189 }
1190
1191 // -----------------------------------------------------------------------------
1192 // Wait/Notify/NotifyAll
1193 //
1194 // Note: a subset of changes to ObjectMonitor::wait()
1195 // will need to be replicated in complete_exit
1196 void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
1197 Thread * const Self = THREAD;
1198 assert(Self->is_Java_thread(), "Must be Java thread!");
1199 JavaThread *jt = (JavaThread *)THREAD;
1200
1201 assert(InitDone, "Unexpectedly not initialized");
1202
1203 CHECK_OWNER(); // Throws IMSE if not owner.
1204
1205 EventJavaMonitorWait event;
1206
1207 // check for a pending interrupt
1208 if (interruptible && jt->is_interrupted(true) && !HAS_PENDING_EXCEPTION) {
1209 // post monitor waited event. Note that this is past-tense, we are done waiting.
1210 if (JvmtiExport::should_post_monitor_waited()) {
1211 // Note: 'false' parameter is passed here because the
1212 // wait was not timed out due to thread interrupt.
1213 JvmtiExport::post_monitor_waited(jt, this, false);
1214
1215 // In this short circuit of the monitor wait protocol, the
1216 // current thread never drops ownership of the monitor and
1217 // never gets added to the wait queue so the current thread
1218 // cannot be made the successor. This means that the
1219 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally
1220 // consume an unpark() meant for the ParkEvent associated with
1221 // this ObjectMonitor.
1222 }
1223 if (event.should_commit()) {
1224 post_monitor_wait_event(&event, this, 0, millis, false);
1225 }
1226 THROW(vmSymbols::java_lang_InterruptedException());
1227 return;
1228 }
1258 exit(true, Self); // exit the monitor
1259 guarantee(_owner != Self, "invariant");
1260
1261 // The thread is on the WaitSet list - now park() it.
1262 // On MP systems it's conceivable that a brief spin before we park
1263 // could be profitable.
1264 //
1265 // TODO-FIXME: change the following logic to a loop of the form
1266 // while (!timeout && !interrupted && _notified == 0) park()
1267
1268 int ret = OS_OK;
1269 int WasNotified = 0;
1270 { // State transition wrappers
1271 OSThread* osthread = Self->osthread();
1272 OSThreadWaitState osts(osthread, true);
1273 {
1274 ThreadBlockInVM tbivm(jt);
1275 // Thread is in thread_blocked state and oop access is unsafe.
1276 jt->set_suspend_equivalent();
1277
1278 if (interruptible && (jt->is_interrupted(false) || HAS_PENDING_EXCEPTION)) {
1279 // Intentionally empty
1280 } else if (node._notified == 0) {
1281 if (millis <= 0) {
1282 Self->_ParkEvent->park();
1283 } else {
1284 ret = Self->_ParkEvent->park(millis);
1285 }
1286 }
1287
1288 // were we externally suspended while we were waiting?
1289 if (ExitSuspendEquivalent (jt)) {
1290 // TODO-FIXME: add -- if succ == Self then succ = null.
1291 jt->java_suspend_self();
1292 }
1293
1294 } // Exit thread safepoint: transition _thread_blocked -> _thread_in_vm
1295
1296 // Node may be on the WaitSet, the EntryList (or cxq), or in transition
1297 // from the WaitSet to the EntryList.
1298 // See if we need to remove Node from the WaitSet.
1384 guarantee(node.TState == ObjectWaiter::TS_RUN, "invariant");
1385 assert(_owner == Self, "invariant");
1386 assert(_succ != Self, "invariant");
1387 } // OSThreadWaitState()
1388
1389 jt->set_current_waiting_monitor(NULL);
1390
1391 guarantee(_recursions == 0, "invariant");
1392 _recursions = save; // restore the old recursion count
1393 _waiters--; // decrement the number of waiters
1394
1395 // Verify a few postconditions
1396 assert(_owner == Self, "invariant");
1397 assert(_succ != Self, "invariant");
1398 assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
1399
1400 // check if the notification happened
1401 if (!WasNotified) {
1402 // no, it could be timeout or Thread.interrupt() or both
1403 // check for interrupt event, otherwise it is timeout
1404 if (interruptible && jt->is_interrupted(true) && !HAS_PENDING_EXCEPTION) {
1405 THROW(vmSymbols::java_lang_InterruptedException());
1406 }
1407 }
1408
1409 // NOTE: Spurious wake up will be consider as timeout.
1410 // Monitor notify has precedence over thread interrupt.
1411 }
1412
1413
1414 // Consider:
1415 // If the lock is cool (cxq == null && succ == null) and we're on an MP system
1416 // then instead of transferring a thread from the WaitSet to the EntryList
1417 // we might just dequeue a thread from the WaitSet and directly unpark() it.
1418
1419 void ObjectMonitor::INotify(Thread * Self) {
1420 Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
1421 ObjectWaiter * iterator = DequeueWaiter();
1422 if (iterator != NULL) {
1423 guarantee(iterator->TState == ObjectWaiter::TS_WAIT, "invariant");
1424 guarantee(iterator->_notified == 0, "invariant");
|