A question about the use of ObjectMonitor::_succ in fastpath exit()
David Holmes
david.holmes at oracle.com
Tue Nov 5 16:15:12 PST 2013
Just as an update on this it does appear that there is a bug in the code
and we seem to be seeing it manifest with some tests. Another engineer
is working on a resolution.
David
On 19/10/2013 9:44 PM, David Holmes wrote:
> Hi,
>
> There is nothing "very obvious" about the ObjectMonitor code! it is
> highly optimized and exceedingly complex - complicated further by
> numerous tuning knobs, a selection of potential policies and the
> experimental SyncFlags.
>
> I can't give you a precise answer to your question, I will simply refer
> to the documentation in objectMonitor.cpp regarding "stranding" and the
> use of timed-parks to provide progress guarantees. It may also be that
> even though marked as _succ the thread in question is still linked into
> one of the queues and so will be seen by the exiting thread. But it
> would take me a while to step through the code and work out exactly what
> happens in this scenario.
>
> David
>
> 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 ?
>>
>> Advance apologies if I am missing something very obvious/fundamental
>> here.
>>
>> Thanks
>>
>> Karthik M
More information about the hotspot-runtime-dev
mailing list