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 ofx
are completed before thefetch_sub
(see here). Thus, if we happen to reach pointA
then all uses ofx
are complete.At point
A
in the code, we are not guaranteed by the standard to see the latest value ofx
until after thememory_order_acquire
fence...
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?