]> 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:24:52 +0000 (22:24 +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/atomic.h
lib/isc/include/isc/refcount.h

index 34344e244b205bdf8454fe761c0f9d934c4a0d68..420a94702833f3ba26ffd8047777de1564499881 100644 (file)
@@ -65,6 +65,8 @@
        atomic_fetch_or_explicit((o), (v), memory_order_release)
 #define atomic_exchange_acq_rel(o, v) \
        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) \
        atomic_compare_exchange_weak_explicit(        \
                (o), (e), (d), memory_order_acq_rel, memory_order_acquire)
index 74543d471f7db71d3409d1b4abc572b04f406f00..6def63f8bda152d45fbcff1bf7f668940b96d0a0 100644 (file)
@@ -118,7 +118,7 @@ isc_refcount_increment(isc_refcount_t *target) {
 static inline uint_fast32_t
 isc_refcount_decrement(isc_refcount_t *target) {
        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);
        return (__v);
 }
@@ -127,7 +127,7 @@ isc_refcount_decrement(isc_refcount_t *target) {
        ({                                                 \
                /* cppcheck-suppress shadowVariable */     \
                uint_fast32_t __v;                         \
-               __v = atomic_fetch_sub_release(target, 1); \
+               __v = atomic_fetch_sub_acq_rel(target, 1); \
                INSIST(__v > 0);                           \
                __v;                                       \
        })