A question about the use of ObjectMonitor::_succ in fastpath exit()

David Holmes david.holmes at oracle.com
Fri Nov 15 09:00:22 PST 2013


On 19/10/2013 5:49 AM, BB wrote:
> Hi,
>
> I have a question about the way ObjectMonitor::_succ is used in the
> ObjectMonitor::exit() fast-path.
>
> If a wait()'ing thread(tA) is notified and assigned to _succ, but
> another thread(tB) grabs the lock.
> tA parks itself because it can't get the lock.
> tB is now done with the lock and it does a fast-path exit because _succ
> != null ?.
> Now how is tA woken up ?
>
> The following table explains the scenario:
> (I have assumed default values for SyncFlags and other knobs)
>
> -----------------------------------------------------------------------------------------------------------------
>       Thread 1(t1)     |    Thread 2(t2)     |   Thread 3(t3)       |
> ObjectMonitor state for obj1's inflated mon
> -----------------------------------------------------------------------------------------------------------------
> synchronized(obj1)    |                     |                      |
> _owner  _succ _EntryList _WaitSet _Resposible
> {                     |                     |                      | t1
>       0     0          0        t1
>                        |                     |                      |
>      obj1.wait()       |                     |                      | t1
>       0     0          t1       t1
>         exit           |                     |                      | 0
>        0     0          t1       0
>         park()         |                     |                      |
>                        |synchronized(obj1)   |                      |
>                        |{                    |                      | t2
>       0     0          t1       t2
>                        |                     |                      |
> obj1.notify();    |                      | t2      0     t1         0
>       t2
>                        |}[exit]              |                      | 0
>        t1    t1         0        0
>         unpark();      |                     |                      |
>                        |            (before t1 reacquires the lock, t3
> jumps in and does a fast path CAS aquire of the lock)
>                        |                     |                      |
>                        |                     | synchronized(obj1){  | t3
>       t1    t1         0        0
>                        |                     |                      |
>         ReEnterI()     |                     |                      |
>         TryLock        |                     |                      |
>         park()         |                     |    obj1.notify();    | t3
>       t1    t1         0        0
>                        |                     |}[exit]               | 0
>        t1    t1         0        0
>                        |                     |                      |
>   // t3 does a fast path exit() as _succ != null
>                        |                     |                      |
>   ----------------------------------------------------------------------------------------------------------------
>
> Now who wakes up t1 ? How is progress guaranteed in such scenarios ?

t1 won't actually park without checking if the lock is now available - 
which it is. If t1 does park then it clears _succ upon wakeup. Look at 
the main loop in ReenterI. Note that park/unpark are stateful operations 
so it is okay for the park to occur after the associated unpark.

David
-----

> Advance apologies if I am missing something very obvious/fundamental here.
>
> Thanks
>
> Karthik M


More information about the hotspot-runtime-dev mailing list