vendredi 8 novembre 2019

Is memory_order_acquire on reference counted pointers to trivially destructible types superfluous?

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;
}
  1. We know that, due to memory_order_release, all reads/writes of x are completed before the fetch_sub (see here). Thus, if we happen to reach point A then all uses of x are complete.

  2. At point A in the code, we are not guaranteed by the standard to see the latest value of x until after the memory_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?

Aucun commentaire:

Enregistrer un commentaire