While
if (isc_refcount_decrement() == 1) { // memory_order_release
isc_refcount_destroy(); // memory_order_acquire
...
}
is theoretically the most efficent in practice, using
memory_order_acq_rel produces the same code on x86_64 and doesn't
trigger tsan data races (which use a idealistic model) if
isc_refcount_destroy() is not called immediately. In fact
isc_refcount_destroy() could be removed if we didn't want
to check for the count being 0 when isc_refcount_destroy() is
called.
https://stackoverflow.com/questions/
49112732/memory-order-in-shared-pointer-destructor
(cherry picked from commit
6278899a3849b7ee46b6460dff93e555e77d99a2)
unsigned int *_tmp = (unsigned int *)(tp); \
int32_t prev; \
prev = atomic_fetch_sub_explicit \
- (&(rp)->refs, 1, memory_order_relaxed); \
+ (&(rp)->refs, 1, memory_order_acq_rel); \
ISC_REQUIRE(prev > 0); \
if (_tmp != NULL) \
*_tmp = prev - 1; \