]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use memory_order_acq_rel in isc_refcount_decrement.
authorMark Andrews <marka@isc.org>
Tue, 25 Aug 2020 12:42:27 +0000 (22:42 +1000)
committerMark Andrews <marka@isc.org>
Tue, 1 Sep 2020 12:31:52 +0000 (22:31 +1000)
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)

lib/isc/include/isc/refcount.h

index f9d6ea039259f3387d2fa56a591832d853e1feef..f79e6290ab7e9c9efd8ec586119196fe0add2559 100644 (file)
@@ -152,7 +152,7 @@ typedef struct isc_refcount {
                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;                       \