问题
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?
回答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.
来源:https://stackoverflow.com/questions/25304201/why-there-need-memory-order-limit-on-reference-counter