3

I'm translating a small C++ snippet to java, and I'm not 100% confident around memory orderings/fences. Is this correct:

C++:

std::atomic<size_t> seq;
...
seq.store(1,std::memory_order_release);
...
seq.load(std::memory_order_acquire);

How I think it should translate to Java:

unsafe.putLong(addr,1);
unsafe.storeFence();

unsafe.getLong(addr);
unsafe.loadFence();

Is this along the right lines? (and yes there is a reason for using unsafe vs just using an AtomicLong)

3
  • Its just a guess, but I'd assume that you have to put the load fence before the getLong call. Commented Mar 26, 2015 at 18:53
  • my understanding (which may be wrong) is that loadFence will flush all reordered/pending loads sat in reorder buffer, so I'm not sure how this would help before a load operation. In my head a storeFence immediately prior to a load would seem to make sense but this isn't how the C++ was written Commented Mar 26, 2015 at 19:10
  • Sorry, my mistake. It is the other way round. See my answer, for an explanation. Commented Mar 26, 2015 at 21:10

1 Answer 1

2

The correct ordering ist as follows:

unsafe.storeFence(); // this fence has to come before the store!
unsafe.putLong(addr,1);

unsafe.getLong(addr);
unsafe.loadFence();

The purpose of the c++ code is usually to ensure, that all stores, which have happened before seq.store(1,std::memory_order_release) in one thread are visible to all loads after seq.load(std::memory_order_acquire); in another thread, as soon as the store of 1 to seq itself becomes visible.

In order to transfer this to Java, you have to ensure, that no loads are reordered before unsafe.getLong(addr); and no stores are reordered after unsafe.putLong(addr,1);
If you put the storeFence behind the store, you don't get any guarantees about how that store is reordered compared to any other store.

If your c++ code has a different purpose, the answer might vary but for that you'd have to show an example code that demonstrates what you are trying to achieve.

Sign up to request clarification or add additional context in comments.

3 Comments

You sure on this? Lets say I previously had other stores into the same memory address that might get reordered. I only care that my load sees the "1" value, and not any of the previous stores, so why do I need to storeFence before I perform the "important" store?
@overclockwise: I'm pretty sure, unless your atomics are used in a very strange manner. Btw: the loads and stores are performed in different threads right (otherwise you wouldn't need atomics)? Maybe you should show more of your program - otherwise, there is always some guesswork about their purpose involved.
@overcockwise: I don't know about java's unsafe.put and get, but at least in C++, you would not see any reordered write accesses to the same memory location (in the same thread) even with relaxed memory ordering and it also would not reorder a load before a store to the same address (in the same thread).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.