Memory ordering properties of Atomic::r-m-w operations

Andrew Haley aph at redhat.com
Tue Nov 8 10:18:09 UTC 2016


On 08/11/16 01:11, David Holmes wrote:
> On 6/11/2016 8:54 PM, Andrew Haley wrote:
>> On 05/11/16 18:43, David Holmes wrote:
>>> Forking new discussion from:
>>>
>>> RFR(M): 8154736: enhancement of cmpxchg and copy_to_survivor for ppc64
>>>
>>> On 1/11/2016 7:44 PM, Andrew Haley wrote:
>>>> On 31/10/16 21:30, David Holmes wrote:
> 
>>  if you have
>>
>> store_relaxed(a)
>> load_seq_cst(b)
>> store_seq_cst(c)
>> load_relaxed(d)
>>
>> there's nothing to prevent
>>
>> load_seq_cst(b)
>> load_relaxed(d)
>> store_relaxed(a)
>> store_seq_cst(c)
>>
>> It is true that neither store a nor load d have moved across this
>> operation, but they have exchanged places.  As far as GCC is concerned
>> this is a correct implementation, and it does meet the requirement of
>> sequential consistency as defined in the C++ memory model.
>
> It does? Then it emphasises what I just said about not knowing what it 
> means to implement an operation with seq_cst semantics.

I take your point, but seq_cst is not a real mystery, it's just a
matter of looking it up: it's all defined in the C++11 standard.  And
it's not significantly different from Java volatile.

> I would have expected full ordering of all loads and stores to get
> "sequential consistency".

Why?  There are only two sequentially-consistent loads and stores in
that block of code.  Of course those two have a total order.  But you
surely wouldn't expect a sequentially-consistent store to be ordered
with respect to a relaxed load.

>> Ouch.  Yes, I agree that something needs fixing.  That comment:
>>
>> // Use release_store_fence to update values like the thread state,
>> // where we don't want the current thread to continue until all our
>> // prior memory accesses (including the new thread state) are visible
>> // to other threads.
>>
>> ... seems very unhelpful, at least because a release fence (using
>> conventional terminology) does not have that property: a release
>> fence is only LoadStore|StoreStore.
> 
> In release_store_fence the release and fence are distinct memory
> ordering components. It is not a store combined with a "release
> fence" but a store between a "release" and a "fence". And critically
> in hotspot that "fence" must have visibility guarantees to ensure
> correctness of Dekker-duality algorithms.

Ah, that is a slightly misleading name.  The "_fence" at the end of
the name is really a StoreLoad fence, got it.  I noticed that once
before, but I'd forgotten.  I guess what's intended here is a
sequentially-consistent store.

> Note the equivalence of release() with LoadStore|StoreStore is a 
> definition within orderAccess.hpp, it is not a general equivalence.

OK.  It would certainly be nice if HotSpot could move to using
standard terminology.  Then, in time, we could just use the C++11
atomics.

Andrew.


More information about the hotspot-dev mailing list