< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page




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


< prev index next >