]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Update 'init_count' atomically to silence tsan errors.
authorMark Andrews <marka@isc.org>
Mon, 7 Sep 2020 06:12:31 +0000 (16:12 +1000)
committerMark Andrews <marka@isc.org>
Tue, 8 Sep 2020 07:41:33 +0000 (17:41 +1000)
lib/dns/rbtdb.c

index 21bd85c322b2f79de8932acc7273163d6e691de0..31ced8e73a5074de3f372e5e216044dff87cbdcc 100644 (file)
@@ -399,6 +399,23 @@ typedef isc_mutex_t nodelock_t;
 #define NODE_WEAKDOWNGRADE(l)   ((void)0)
 #endif
 
+#if defined(ISC_PLATFORM_HAVESTDATOMIC)
+#if defined(__cplusplus)
+#include <isc/stdatomic.h>
+#else
+#include <stdatomic.h>
+#endif
+#define DNS_RBTDB_STDATOMIC 1
+#define DNS_RBTDB_INC(x) atomic_fetch_add(&(x), (1))
+#define DNS_RBTDB_LOAD(x) atomic_load(&(x))
+#elif defined(ISC_PLATFORM_HAVEXADD)
+#define DNS_RBTDB_INC(x) isc_atomic_xadd((int *)&(x), 1);
+#define DNS_RBTDB_LOAD(x) isc_atomic_xadd((int *)&(x), 0);
+#else
+#define DNS_RBTDB_INC(x) ((x)++)
+#define DNS_RBTDB_LOAD(x) (x)
+#endif
+
 /*%
  * Whether to rate-limit updating the LRU to avoid possible thread contention.
  * Our performance measurement has shown the cost is marginal, so it's defined
@@ -457,7 +474,11 @@ typedef struct rdatasetheader {
         * this rdataset.
         */
 
-       uint32_t                    count;
+#ifdef DNS_RBTDB_STDATOMIC
+       _Atomic(uint32_t)                count;
+#else
+       uint32_t                         count;
+#endif
        /*%<
         * Monotonously increased every time this rdataset is bound so that
         * it is used as the base of the starting point in DNS responses
@@ -952,7 +973,11 @@ static char FILE_VERSION[32] = "\0";
  *      that indicates that the database does not implement cyclic
  *      processing.
  */
+#ifdef DNS_RBTDB_STDATOMIC
+static _Atomic(unsigned int) init_count;
+#else
 static unsigned int init_count;
+#endif
 
 /*
  * Locking
@@ -3322,7 +3347,7 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header,
        rdataset->private2 = node;
        raw = (unsigned char *)header + sizeof(*header);
        rdataset->private3 = raw;
-       rdataset->count = isc_atomic_xadd((int32_t*)&header->count, 1);
+       rdataset->count = DNS_RBTDB_INC(header->count);
        if (rdataset->count == UINT32_MAX)
                rdataset->count = 0;
 
@@ -6841,7 +6866,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                newheader->attributes |= RDATASET_ATTR_ZEROTTL;
        newheader->noqname = NULL;
        newheader->closest = NULL;
-       newheader->count = isc_atomic_xadd((int32_t*)&init_count, 1);
+       newheader->count = DNS_RBTDB_INC(init_count);
        newheader->trust = rdataset->trust;
        newheader->additional_auth = NULL;
        newheader->additional_glue = NULL;
@@ -7037,7 +7062,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
        newheader->trust = 0;
        newheader->noqname = NULL;
        newheader->closest = NULL;
-       newheader->count = isc_atomic_xadd((int32_t*)&init_count, 1);
+       newheader->count = DNS_RBTDB_INC(init_count);
        newheader->additional_auth = NULL;
        newheader->additional_glue = NULL;
        newheader->last_used = 0;
@@ -7483,7 +7508,7 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
        newheader->serial = 1;
        newheader->noqname = NULL;
        newheader->closest = NULL;
-       newheader->count = isc_atomic_xadd((int32_t*)&init_count, 1);
+       newheader->count = DNS_RBTDB_INC(init_count);
        newheader->additional_auth = NULL;
        newheader->additional_glue = NULL;
        newheader->last_used = 0;