diff options
author | vkalintiris <vasilis@netdata.cloud> | 2024-02-01 16:36:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-01 16:36:17 +0200 |
commit | 2e459de7ecb985162b48c65ebfa742e5d745af8c (patch) | |
tree | 83519f1caca4ef698b4e1915b8ae180354ff3fe1 /src | |
parent | a25ff1b401c2b9dfd0289a243c1f09a9bceba2e1 (diff) |
Use spinlock for reference counting. (#16901)
Diffstat (limited to 'src')
-rw-r--r-- | src/database/engine/metric.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/src/database/engine/metric.c b/src/database/engine/metric.c index 97829da825..9922d93273 100644 --- a/src/database/engine/metric.c +++ b/src/database/engine/metric.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "metric.h" #include "cache.h" +#include "libnetdata/locks/locks.h" #include "rrddiskprotocol.h" typedef int32_t REFCOUNT; @@ -16,6 +17,8 @@ struct metric { uint32_t latest_update_every_s; // the latest data collection frequency pid_t writer; uint8_t partition; + + SPINLOCK refcount_spinlock; REFCOUNT refcount; // THIS IS allocated with malloc() @@ -131,17 +134,17 @@ static inline time_t mrg_metric_get_first_time_s_smart(MRG *mrg __maybe_unused, } static inline REFCOUNT metric_acquire(MRG *mrg __maybe_unused, METRIC *metric) { - size_t partition = metric->partition; - REFCOUNT expected = __atomic_load_n(&metric->refcount, __ATOMIC_RELAXED); - REFCOUNT refcount; + spinlock_lock(&metric->refcount_spinlock); - do { - if(expected < 0) - fatal("METRIC: refcount is %d (negative) during acquire", metric->refcount); + if (metric->refcount >= 0) + metric->refcount += 1; + else + fatal("METRIC: refcount is %d (negative) during acquire", metric->refcount); - refcount = expected + 1; - } while(!__atomic_compare_exchange_n(&metric->refcount, &expected, refcount, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)); + REFCOUNT refcount = metric->refcount; + spinlock_unlock(&metric->refcount_spinlock); + size_t partition = metric->partition; if(refcount == 1) __atomic_add_fetch(&mrg->index[partition].stats.entries_referenced, 1, __ATOMIC_RELAXED); @@ -151,17 +154,17 @@ static inline REFCOUNT metric_acquire(MRG *mrg __maybe_unused, METRIC *metric) { } static inline bool metric_release_and_can_be_deleted(MRG *mrg __maybe_unused, METRIC *metric) { - size_t partition = metric->partition; - REFCOUNT expected = __atomic_load_n(&metric->refcount, __ATOMIC_RELAXED); - REFCOUNT refcount; + spinlock_lock(&metric->refcount_spinlock); - do { - if(expected <= 0) - fatal("METRIC: refcount is %d (zero or negative) during release", metric->refcount); + if (metric->refcount <= 0) + fatal("METRIC: refcount is %d (zero or negative) during release", metric->refcount); - refcount = expected - 1; - } while(!__atomic_compare_exchange_n(&metric->refcount, &expected, refcount, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)); + metric->refcount -= 1; + REFCOUNT refcount = metric->refcount; + spinlock_unlock(&metric->refcount_spinlock); + + size_t partition = metric->partition; if(unlikely(!refcount)) __atomic_sub_fetch(&mrg->index[partition].stats.entries_referenced, 1, __ATOMIC_RELAXED); @@ -223,6 +226,7 @@ static inline METRIC *metric_add_and_acquire(MRG *mrg, MRG_ENTRY *entry, bool *r metric->writer = 0; metric->refcount = 0; metric->partition = partition; + spinlock_init(&metric->refcount_spinlock); metric_acquire(mrg, metric); *PValue = metric; |