On 31/07/2015 5:54 AM, Kim Barrett wrote:
On Jul 30, 2015, at 8:09 AM, David Holmes <david.hol...@oracle.com> wrote:

On 30/07/2015 9:57 PM, Peter Levart wrote:
'r' has been enqueued.

Thread-1:

r.isEnqueued() &&
q.poll() == null &&
r.isEnqueued()

Thread-2:

q.poll();


Sequence of actions:

T1: r.isEnqueued() ==> true

T2: q.poll() executed to the following point (see HERE) and 'r' was the
last element in the queue ('head' has been assigned to null):

Yeah thanks - just realized it is that darned unsynchronized "fast-path" again. 
What a mess.

It a kind of inverse of the original problem.

Original: don't update reference state to enqueued before the queue is updated
This one: don't update the queue state to empty before the reference state 
shows it is de-queued.

So yes the fix here is to move "r.queue = null" to before the assignment to 
head.

Bring on the next race ;-)

I agree with everything David said above.  Bleh!

So I think I can either:

1. Go ahead with my change + Peter's change.

2. Give this back to core-libs while I step carefully away :-)

I *think* option (1) is at least an improvement.  But I completely
missed Peter's race, despite having specifically looked for problems
there, so take my opinion with an appropriate quantity of salt.

I vote for 1 as well. I think we have now given good coverage to the two sources of problems (the two lock-free regions):
- reference queue state can be seen while queue state is in transition
- queue empty state can be seen while reference state is in transition

Oh for a tool that would do this analysis for us :(

Thanks,
David


Reply via email to