[concurrency-interest] AtomicReference.updateAndGet() mandatory updating

Gil Tene gil at azul.com
Fri May 26 11:25:14 EDT 2017



Sent from Gil's iPhone

> On May 26, 2017, at 8:19 AM, Gil Tene <gil at azul.com> wrote:
> 
> 
> 
> Sent from Gil's iPhone
> 
>>> On May 26, 2017, at 7:07 AM, Andrew Dinn <adinn at redhat.com> wrote:
>>> 
>>>> On 26/05/17 14:35, Andrew Haley wrote:
>>>>> On 26/05/17 13:56, Andrew Dinn wrote:
>>>>> On 26/05/17 13:46, Doug Lea wrote:
>>>>> On 05/26/2017 04:44 AM, Andrew Haley wrote:
>>>>> 
>>>>>>> a compareAndSet has the memory semantics of a volatile
>>>>>>> write regardless of whether or not the write occurred. 
>>>>>> That property of compareAndSet is very ugly, and is a pain to
>>>>>> implement. Most of the CAS instructions I know about don't have such
>>>>>> a property, and making it work requires either an unconditional full
>>>>>> fence after every CAS or a conditional one if it fails.  Either way
>>>>>> sucks mightily and is unlikely to be useful except in the most
>>>>>> pathological cases.
>>>>> 
>>>>> Initially (in Java5) requiring it has led to some questionable reliance.
>>>>> So we cannot change it. But there's not much motivation to do so anyway:
>>>>> As implied by Nathan Reynolds, encountering some (local) fence overhead
>>>>> on CAS failure typically reduces contention and may improve throughput.
>>>> 
>>>> It would be useful to know if that reduction in contention is specific
>>>> to, say, x86 hardware or also occurs on weak memory architectures like
>>>> AArch64 or ppc. Perhaps Nathan could clarify that?
>>> 
>>> Just thinking about AArch64, and how to implement such a thing as well
>>> as possible.  We can't do a store release to the variable involved in
>>> the CAS, but perhaps we could do a store release to something local to
>>> the thread.  That would be better than a full fence, which would be
>>> overkill for this purpose.  Unlike x86 we can't do an access outside
>>> the stack.  I'm trying to think of something in memory, probably in
>>> the local cache, that can be clobbered, but nothing comes to mind.
>>> OK, here's a mad idea: we could allocate an extra stack slot in a
>>> method which uses
>> 
>> Would a store release into a dummy field of the JavaThread instance be
>> better? This would avoid wasting stack space.
> 
> I believe that making the hardware perform a store release [or equivalent] to a different location is not sufficient to emulate a volatile write's memory semantics, since it e.g. does not prevent subsequent volatile loads of other fields from floating backwards past the store release point, and then e.g. past prior non-volatile stores to the compareAndSet'ed field.
> 
> Basically, there is no StoreLoad ordering [that is required to be] enforced on the hardware by a store release, which makes it insufficient.
> 
> Unfortunately, to provide the spec'ed (and the often expected by lay people) behavior, you need to force the hardware to impose a StoreLoad order with the compareAndSet even if the CAS instruction never wrote. If the hardware does not do that in a compare-failing CAS instruction, the code surrounding the CAS obstruction needs to..

Obviously, this is assuming that the compareAndSet memory semantics on VarHandles are changed back to what j.u.c.atomic semantics were for compareAndSet in Java 8... before this fix, a StoreLoad on a compare-failing CAS instruction is not required.

>> 
>> regards,
>> 
>> 
>> Andrew Dinn
>> -----------
>> Senior Principal Software Engineer
>> Red Hat UK Ltd
>> Registered in England and Wales under Company Registration No. 03798903
>> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


More information about the Concurrency-interest mailing list