libc++ shared_ptr implementation release()
for the sake of simplicity can be depicted as:
void release()
{
if (ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1)
{
delete this;
}
}
Why doesn't libc++ split it into release decrement and acquire fence?
void release()
{
if (ref_count.fetch_sub(1, std::memory_order_release) == 1)
{
std::atomic_thread_fence(std::memory_order_acquire);
delete this;
}
}
as Boost recommends, which looks superior as it doesn't impose acquire mem order for all but the last decrement.
shared_ptr
but never actually shares it. – Youngerfetch_sub
and T2 destruction of the reference controller – Selenastd::atomic_thread_fence
being a more restrictive fence than one tied to an operation. – Pantryshared_ptr
objects are actually shared, but many others aren't, the non-shared case is still the common one. But the code-gen would still have to be correct for actually-shared objects, so you can't just avoid the work entirely. – Durableseq_cst
andstd::atomic_thread_fence(std::memory_order_acquire)
is a no-op. – Younger