* 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) \
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)
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; \
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; \
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
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);
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);
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;
}
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