2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

Use memory_order_acq_rel in isc_refcount_decrement.

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
This commit is contained in:
Mark Andrews 2020-08-25 22:42:27 +10:00
parent fcd6962e8b
commit 6278899a38
2 changed files with 4 additions and 2 deletions

View File

@ -65,6 +65,8 @@
atomic_fetch_or_explicit((o), (v), memory_order_release) atomic_fetch_or_explicit((o), (v), memory_order_release)
#define atomic_exchange_acq_rel(o, v) \ #define atomic_exchange_acq_rel(o, v) \
atomic_exchange_explicit((o), (v), memory_order_acq_rel) atomic_exchange_explicit((o), (v), memory_order_acq_rel)
#define atomic_fetch_sub_acq_rel(o, v) \
atomic_fetch_sub_explicit((o), (v), memory_order_acq_rel)
#define atomic_compare_exchange_weak_acq_rel(o, e, d) \ #define atomic_compare_exchange_weak_acq_rel(o, e, d) \
atomic_compare_exchange_weak_explicit( \ atomic_compare_exchange_weak_explicit( \
(o), (e), (d), memory_order_acq_rel, memory_order_acquire) (o), (e), (d), memory_order_acq_rel, memory_order_acquire)

View File

@ -118,7 +118,7 @@ isc_refcount_increment(isc_refcount_t *target) {
static inline uint_fast32_t static inline uint_fast32_t
isc_refcount_decrement(isc_refcount_t *target) { isc_refcount_decrement(isc_refcount_t *target) {
uint_fast32_t __v; uint_fast32_t __v;
__v = (uint_fast32_t)atomic_fetch_sub_release(target, 1); __v = (uint_fast32_t)atomic_fetch_sub_acq_rel(target, 1);
INSIST(__v > 0); INSIST(__v > 0);
return (__v); return (__v);
} }
@ -127,7 +127,7 @@ isc_refcount_decrement(isc_refcount_t *target) {
({ \ ({ \
/* cppcheck-suppress shadowVariable */ \ /* cppcheck-suppress shadowVariable */ \
uint_fast32_t __v; \ uint_fast32_t __v; \
__v = atomic_fetch_sub_release(target, 1); \ __v = atomic_fetch_sub_acq_rel(target, 1); \
INSIST(__v > 0); \ INSIST(__v > 0); \
__v; \ __v; \
}) })