This question is specifically about trivially destructible types within reference counted pointers. See the example from Boost's documentation on uses of atomics.
The decrement is as follows:
if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
// A
boost::atomic_thread_fence(boost::memory_order_acquire);
delete x;
}
We know that, due to
memory_order_release, all reads/writes ofxare completed before thefetch_sub(see here). Thus, if we happen to reach pointAthen all uses ofxare complete.At point
Ain the code, we are not guaranteed by the standard to see the latest value ofxuntil after thememory_order_acquirefence...
So here is my question regarding the second statement about memory_order_acquire:
When x points to a trivially destructible type (for example, int where x is int * const) is the memory_order_acquire pointless? The rationale I have is because if x is trivially destructible then the latest changes to x does no affect the deletion of x?
For example, whether the deleting thread's delete x; sees the latest x such that *x = 10 or an outdated value such that *x = 8 the destruction process is always the same regardless (as long as the pointer x itself remains constant). It knows that no one is going to modify the x from that point thanks to the release and so all it has to do is deallocate.
Is there another benefit of memory_order_acquire that I am missing here?
Is my thinking correct and if not then why do we need to see the latest value of x on the deleting thread?