]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make lib/isc/stats.c lock-free
authorOndřej Surý <ondrej@sury.org>
Wed, 1 Aug 2018 07:07:09 +0000 (09:07 +0200)
committerOndřej Surý <ondrej@sury.org>
Wed, 8 Aug 2018 07:49:06 +0000 (09:49 +0200)
lib/isc/include/isc/refcount.h
lib/isc/stats.c
lib/isccfg/aclconf.c

index 6ef8fcbe1e37bd9499c4f0f3a7ca4075ba8b40d3..0c8a7def9f74fc62a9f3ed7b728cf9da1220ee60 100644 (file)
@@ -90,14 +90,12 @@ ISC_LANG_BEGINDECLS
  * Sample implementations
  */
 
-typedef struct isc_refcount {
-       atomic_int_fast32_t refs;
-} isc_refcount_t;
+typedef atomic_int_fast32_t isc_refcount_t;
 
-#define isc_refcount_init(rp, n) atomic_init(&(rp)->refs, n)
+#define isc_refcount_init(rp, n) atomic_init(rp, n)
 
 #define isc_refcount_current(rp)                                       \
-       ((unsigned int)(atomic_load_explicit(&(rp)->refs,               \
+       ((unsigned int)(atomic_load_explicit(rp,                        \
                                             memory_order_acquire)))
 
 #define isc_refcount_destroy(rp)                               \
@@ -111,7 +109,7 @@ typedef struct isc_refcount {
                unsigned int *_tmp = (unsigned int *)(tp);      \
                isc_int32_t prev;                               \
                prev = atomic_fetch_add_explicit                \
-                       (&(rp)->refs, 1, memory_order_relaxed); \
+                       (rp, 1, memory_order_relaxed); \
                if (_tmp != NULL)                               \
                        *_tmp = prev + 1;                       \
        } while (0)
@@ -121,7 +119,7 @@ typedef struct isc_refcount {
                unsigned int *_tmp = (unsigned int *)(tp);      \
                isc_int32_t prev;                               \
                prev = atomic_fetch_add_explicit                \
-                       (&(rp)->refs, 1, memory_order_relaxed); \
+                       (rp, 1, memory_order_relaxed); \
                ISC_REQUIRE(prev > 0);                          \
                if (_tmp != NULL)                               \
                        *_tmp = prev + 1;                       \
@@ -132,7 +130,7 @@ typedef struct isc_refcount {
                unsigned int *_tmp = (unsigned int *)(tp);      \
                isc_int32_t prev;                               \
                prev = atomic_fetch_sub_explicit                \
-                       (&(rp)->refs, 1, memory_order_release); \
+                       (rp, 1, memory_order_release); \
                ISC_REQUIRE(prev > 0);                          \
                if (_tmp != NULL)                               \
                        *_tmp = prev - 1;                       \
index 1f640515cb3f4af833de008765359966879fdf85..1ec66ada6f305dc0b5c4ce2c41408730ac00b938 100644 (file)
@@ -39,8 +39,7 @@ struct isc_stats {
        isc_mem_t       *mctx;
        int             ncounters;
 
-       isc_mutex_t     lock;
-       unsigned int    references; /* locked by lock */
+       isc_refcount_t  references; /* locked by lock */
 
        /*%
         * Locked by counterlock or unlocked if efficient rwlock is not
@@ -70,26 +69,24 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
        REQUIRE(statsp != NULL && *statsp == NULL);
 
        stats = isc_mem_get(mctx, sizeof(*stats));
-       if (stats == NULL)
+       if (stats == NULL) {
                return (ISC_R_NOMEMORY);
-
-       result = isc_mutex_init(&stats->lock);
-       if (result != ISC_R_SUCCESS)
-               goto clean_stats;
+       }
 
        stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters);
        if (stats->counters == NULL) {
                result = ISC_R_NOMEMORY;
-               goto clean_mutex;
+               goto cleanup;
        }
        stats->copiedcounters = isc_mem_get(mctx,
                                            sizeof(isc_uint64_t) * ncounters);
        if (stats->copiedcounters == NULL) {
                result = ISC_R_NOMEMORY;
-               goto clean_counters;
+               goto cleanup;
        }
 
-       stats->references = 1;
+       isc_refcount_init(&stats->references, 1);
+
        memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters);
        stats->mctx = NULL;
        isc_mem_attach(mctx, &stats->mctx);
@@ -100,13 +97,11 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
 
        return (result);
 
-clean_counters:
-       isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters);
-
-clean_mutex:
-       DESTROYLOCK(&stats->lock);
+cleanup:
+       if (stats->counters != NULL) {
+               isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters);
+       }
 
-clean_stats:
        isc_mem_put(mctx, stats, sizeof(*stats));
 
        return (result);
@@ -117,9 +112,8 @@ isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) {
        REQUIRE(ISC_STATS_VALID(stats));
        REQUIRE(statsp != NULL && *statsp == NULL);
 
-       LOCK(&stats->lock);
-       stats->references++;
-       UNLOCK(&stats->lock);
+       unsigned int refs;      
+       isc_refcount_increment(&stats->references, &refs);
 
        *statsp = stats;
 }
@@ -133,21 +127,19 @@ isc_stats_detach(isc_stats_t **statsp) {
        stats = *statsp;
        *statsp = NULL;
 
-       LOCK(&stats->lock);
-       stats->references--;
+       unsigned int refs;
+       isc_refcount_decrement(&stats->references, &refs);
 
-       if (stats->references == 0) {
+       if (refs == 0) {
+               isc_refcount_destroy(&stats->references);
+               
                isc_mem_put(stats->mctx, stats->copiedcounters,
                            sizeof(isc_stat_t) * stats->ncounters);
                isc_mem_put(stats->mctx, stats->counters,
                            sizeof(isc_stat_t) * stats->ncounters);
-               UNLOCK(&stats->lock);
-               DESTROYLOCK(&stats->lock);
                isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
-               return;
        }
-
-       UNLOCK(&stats->lock);
+       return;
 }
 
 int
index 67f013e704d6f733e9881dd557804b0a970b3894..44b5bed36ad766b922f88d908a31ae5c2140cc48 100644 (file)
@@ -34,7 +34,6 @@
 isc_result_t
 cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret) {
        cfg_aclconfctx_t *actx;
-
        
        REQUIRE(ret != NULL && *ret == NULL);