2

In the example of boost::atomic, the unref function:

void intrusive_ptr_release(const X * x)
{
  if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
    boost::atomic_thread_fence(boost::memory_order_acquire);
    delete x;
  }
}

1: the fetch_sub op is limited by memory_order_release, which prevents preceding operations to be reordered past the point. But what are the possible scenes that would have such phenomenon?

2: in addition of memory_order_release on the atomic op, why there is an additional memory_order_acquire before the deletion?

3

1 Answer 1

1

For the first question, it prevents any use of (*x) to be reordered after the fetch_sub (when the reference count could be 0 and use is therefore banned). Possible causes are CPU reordering or compiler reordering. The second question is just the mirror of the release; release protects stores and acquire protects loads.

It may seem that refcount_fetch_sub(1, memory_order_acq_rel) works as well, but that protects just the refcount.

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

4 Comments

I know both compiler and CPU may reorder commands. However, in this case, the delete x command is dependent on the result of the fetch_sub. Why there are still possibility that things in delete x may be reordered prior to fetch_sub?
In a single-threaded view, reads could be reordered before an unrelated write, i.e. the other members of x may already be read to prevent a pipeline stall if the branch succeeds. And that in turn may cause the deletion of an older version of x when another thread had updated x.
"but that protects just the refcount." What do you mean?
Surely memory_order_acq_rel doesn't just protect the refcount? Rather the separate barrier is used as an optimization, so that it only uses an acquire barrier if the reference count reaches 0?

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.