src/share/vm/runtime/objectMonitor.cpp

Print this page




1583 
1584      // The thread is now either on off-list (TS_RUN),
1585      // on the EntryList (TS_ENTER), or on the cxq (TS_CXQ).
1586      // The Node's TState variable is stable from the perspective of this thread.
1587      // No other threads will asynchronously modify TState.
1588      guarantee (node.TState != ObjectWaiter::TS_WAIT, "invariant") ;
1589      OrderAccess::loadload() ;
1590      if (_succ == Self) _succ = NULL ;
1591      WasNotified = node._notified ;
1592 
1593      // Reentry phase -- reacquire the monitor.
1594      // re-enter contended monitor after object.wait().
1595      // retain OBJECT_WAIT state until re-enter successfully completes
1596      // Thread state is thread_in_vm and oop access is again safe,
1597      // although the raw address of the object may have changed.
1598      // (Don't cache naked oops over safepoints, of course).
1599 
1600      // post monitor waited event. Note that this is past-tense, we are done waiting.
1601      if (JvmtiExport::should_post_monitor_waited()) {
1602        JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
1603      }
1604 
1605      // Without the fix for 8028280, it is possible for the above call:
1606      //
1607      //   Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
1608      //
1609      // to consume the unpark() that was done when the successor was set.
1610      // The solution for this very rare possibility is to redo the unpark()
1611      // outside of the JvmtiExport::should_post_monitor_waited() check.
1612      //
1613      if (node._notified != 0 && _succ == Self) {
1614        // In this part of the monitor wait-notify-reenter protocol it
1615        // is possible (and normal) for another thread to do a fastpath
1616        // monitor enter-exit while this thread is still trying to get
1617        // to the reenter portion of the protocol.
1618        //
1619        // The ObjectMonitor was notified and the current thread is
1620        // the successor which also means that an unpark() has already
1621        // been done. The JVMTI_EVENT_MONITOR_WAITED event handler can
1622        // consume the unpark() that was done when the successor was
1623        // set because the same ParkEvent is shared between Java
1624        // monitors and JVM/TI RawMonitors (for now).
1625        //
1626        // We redo the unpark() to ensure forward progress, i.e., we
1627        // don't want all pending threads hanging (parked) with none
1628        // entering the unlocked monitor.
1629        node._event->unpark();
1630      }

1631 
1632      if (event.should_commit()) {
1633        post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
1634      }
1635 
1636      OrderAccess::fence() ;
1637 
1638      assert (Self->_Stalled != 0, "invariant") ;
1639      Self->_Stalled = 0 ;
1640 
1641      assert (_owner != Self, "invariant") ;
1642      ObjectWaiter::TStates v = node.TState ;
1643      if (v == ObjectWaiter::TS_RUN) {
1644          enter (Self) ;
1645      } else {
1646          guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
1647          ReenterI (Self, &node) ;
1648          node.wait_reenter_end(this);
1649      }
1650 




1583 
1584      // The thread is now either on off-list (TS_RUN),
1585      // on the EntryList (TS_ENTER), or on the cxq (TS_CXQ).
1586      // The Node's TState variable is stable from the perspective of this thread.
1587      // No other threads will asynchronously modify TState.
1588      guarantee (node.TState != ObjectWaiter::TS_WAIT, "invariant") ;
1589      OrderAccess::loadload() ;
1590      if (_succ == Self) _succ = NULL ;
1591      WasNotified = node._notified ;
1592 
1593      // Reentry phase -- reacquire the monitor.
1594      // re-enter contended monitor after object.wait().
1595      // retain OBJECT_WAIT state until re-enter successfully completes
1596      // Thread state is thread_in_vm and oop access is again safe,
1597      // although the raw address of the object may have changed.
1598      // (Don't cache naked oops over safepoints, of course).
1599 
1600      // post monitor waited event. Note that this is past-tense, we are done waiting.
1601      if (JvmtiExport::should_post_monitor_waited()) {
1602        JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);

1603 








1604        if (node._notified != 0 && _succ == Self) {
1605          // In this part of the monitor wait-notify-reenter protocol it
1606          // is possible (and normal) for another thread to do a fastpath
1607          // monitor enter-exit while this thread is still trying to get
1608          // to the reenter portion of the protocol.
1609          //
1610          // The ObjectMonitor was notified and the current thread is
1611          // the successor which also means that an unpark() has already
1612          // been done. The JVMTI_EVENT_MONITOR_WAITED event handler can
1613          // consume the unpark() that was done when the successor was
1614          // set because the same ParkEvent is shared between Java
1615          // monitors and JVM/TI RawMonitors (for now).
1616          //
1617          // We redo the unpark() to ensure forward progress, i.e., we
1618          // don't want all pending threads hanging (parked) with none
1619          // entering the unlocked monitor.
1620          node._event->unpark();
1621        }
1622      }
1623 
1624      if (event.should_commit()) {
1625        post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
1626      }
1627 
1628      OrderAccess::fence() ;
1629 
1630      assert (Self->_Stalled != 0, "invariant") ;
1631      Self->_Stalled = 0 ;
1632 
1633      assert (_owner != Self, "invariant") ;
1634      ObjectWaiter::TStates v = node.TState ;
1635      if (v == ObjectWaiter::TS_RUN) {
1636          enter (Self) ;
1637      } else {
1638          guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ;
1639          ReenterI (Self, &node) ;
1640          node.wait_reenter_end(this);
1641      }
1642