2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

add static macros for ISC_REFCOUNT_DECL/IMPL

this commit adds a mechanism to statically declare attach/detach
and ref/unref methods, for objects that are only accessed within
a single C file.
This commit is contained in:
Evan Hunt
2024-03-12 01:02:48 -07:00
parent bc8095311a
commit a5d0e6c4ba

View File

@@ -119,19 +119,26 @@ typedef atomic_uint_fast32_t isc_refcount_t;
ISC_INSIST(_refs > 0); \ ISC_INSIST(_refs > 0); \
} while (0) } while (0)
#define ISC_REFCOUNT_TRACE_DECL(name) \ #define ISC__REFCOUNT_TRACE_DECL(name, stat) \
name##_t *name##__ref(name##_t *ptr, const char *func, \ stat name##_t *name##__ref(name##_t *ptr, const char *func, \
const char *file, unsigned int line); \ const char *file, unsigned int line); \
void name##__unref(name##_t *ptr, const char *func, const char *file, \ stat void name##__unref(name##_t *ptr, const char *func, \
unsigned int line); \ const char *file, unsigned int line); \
void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \ stat void name##__attach(name##_t *ptr, name##_t **ptrp, \
const char *file, unsigned int line); \ const char *func, const char *file, \
void name##__detach(name##_t **ptrp, const char *func, \ unsigned int line); \
const char *file, unsigned int line) stat name##__detach(name##_t **ptrp, const char *func, \
const char *file, unsigned int line)
#define ISC_REFCOUNT_TRACE_IMPL(name, destroy) \ #define ISC_REFCOUNT_BLANK
name##_t *name##__ref(name##_t *ptr, const char *func, \ #define ISC_REFCOUNT_TRACE_DECL(name) \
const char *file, unsigned int line) { \ ISC__REFCOUNT_TRACE_DECL(name, ISC_REFCOUNT_BLANK)
#define ISC_REFCOUNT_STATIC_TRACE_DECL(name) \
ISC__REFCOUNT_TRACE_DECL(name, static inline)
#define ISC__REFCOUNT_TRACE_IMPL(name, destroy, stat) \
stat name##_t *name##__ref(name##_t *ptr, const char *func, \
const char *file, unsigned int line) { \
REQUIRE(ptr != NULL); \ REQUIRE(ptr != NULL); \
uint_fast32_t refs = \ uint_fast32_t refs = \
isc_refcount_increment(&ptr->references) + 1; \ isc_refcount_increment(&ptr->references) + 1; \
@@ -141,8 +148,8 @@ typedef atomic_uint_fast32_t isc_refcount_t;
return (ptr); \ return (ptr); \
} \ } \
\ \
void name##__unref(name##_t *ptr, const char *func, const char *file, \ stat void name##__unref(name##_t *ptr, const char *func, \
unsigned int line) { \ const char *file, unsigned int line) { \
REQUIRE(ptr != NULL); \ REQUIRE(ptr != NULL); \
uint_fast32_t refs = \ uint_fast32_t refs = \
isc_refcount_decrement(&ptr->references) - 1; \ isc_refcount_decrement(&ptr->references) - 1; \
@@ -154,8 +161,9 @@ typedef atomic_uint_fast32_t isc_refcount_t;
"%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \ "%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \
__func__, func, file, line, isc_tid(), ptr, refs); \ __func__, func, file, line, isc_tid(), ptr, refs); \
} \ } \
void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \ stat void name##__attach(name##_t *ptr, name##_t **ptrp, \
const char *file, unsigned int line) { \ const char *func, const char *file, \
unsigned int line) { \
REQUIRE(ptrp != NULL && *ptrp == NULL); \ REQUIRE(ptrp != NULL && *ptrp == NULL); \
uint_fast32_t refs = \ uint_fast32_t refs = \
isc_refcount_increment(&ptr->references) + 1; \ isc_refcount_increment(&ptr->references) + 1; \
@@ -165,8 +173,8 @@ typedef atomic_uint_fast32_t isc_refcount_t;
*ptrp = ptr; \ *ptrp = ptr; \
} \ } \
\ \
void name##__detach(name##_t **ptrp, const char *func, \ stat void name##__detach(name##_t **ptrp, const char *func, \
const char *file, unsigned int line) { \ const char *file, unsigned int line) { \
REQUIRE(ptrp != NULL && *ptrp != NULL); \ REQUIRE(ptrp != NULL && *ptrp != NULL); \
name##_t *ptr = *ptrp; \ name##_t *ptr = *ptrp; \
*ptrp = NULL; \ *ptrp = NULL; \
@@ -181,37 +189,51 @@ typedef atomic_uint_fast32_t isc_refcount_t;
__func__, func, file, line, isc_tid(), ptr, refs); \ __func__, func, file, line, isc_tid(), ptr, refs); \
} }
#define ISC_REFCOUNT_DECL(name) \ #define ISC_REFCOUNT_TRACE_IMPL(name, destroy) \
name##_t *name##_ref(name##_t *ptr); \ ISC__REFCOUNT_TRACE_DECL(name, destroy, ISC_REFCOUNT_BLANK)
void name##_unref(name##_t *ptr); \ #define ISC_REFCOUNT_STATIC_TRACE_IMPL(name, destroy) \
void name##_attach(name##_t *ptr, name##_t **ptrp); \ ISC__REFCOUNT_TRACE_DECL(name, destroy, static inline)
void name##_detach(name##_t **ptrp)
#define ISC_REFCOUNT_IMPL(name, destroy) \ #define ISC__REFCOUNT_DECL(name, stat) \
name##_t *name##_ref(name##_t *ptr) { \ stat name##_t *name##_ref(name##_t *ptr) __attribute__((unused)); \
stat void name##_unref(name##_t *ptr) __attribute__((unused)); \
stat void name##_attach(name##_t *ptr, name##_t **ptrp) \
__attribute__((unused)); \
stat void name##_detach(name##_t **ptrp) __attribute__((unused))
#define ISC_REFCOUNT_DECL(name) ISC__REFCOUNT_DECL(name, ISC_REFCOUNT_BLANK)
#define ISC_REFCOUNT_STATIC_DECL(name) ISC__REFCOUNT_DECL(name, static inline)
#define ISC__REFCOUNT_IMPL(name, destroy, stat) \
stat name##_t *name##_ref(name##_t *ptr) { \
REQUIRE(ptr != NULL); \ REQUIRE(ptr != NULL); \
isc_refcount_increment(&ptr->references); \ isc_refcount_increment(&ptr->references); \
return (ptr); \ return (ptr); \
} \ } \
\ \
void name##_unref(name##_t *ptr) { \ stat void name##_unref(name##_t *ptr) { \
REQUIRE(ptr != NULL); \ REQUIRE(ptr != NULL); \
if (isc_refcount_decrement(&ptr->references) == 1) { \ if (isc_refcount_decrement(&ptr->references) == 1) { \
isc_refcount_destroy(&ptr->references); \ isc_refcount_destroy(&ptr->references); \
destroy(ptr); \ destroy(ptr); \
} \ } \
} \ } \
void name##_attach(name##_t *ptr, name##_t **ptrp) { \ stat void name##_attach(name##_t *ptr, name##_t **ptrp) { \
REQUIRE(ptrp != NULL && *ptrp == NULL); \ REQUIRE(ptrp != NULL && *ptrp == NULL); \
name##_ref(ptr); \ name##_ref(ptr); \
*ptrp = ptr; \ *ptrp = ptr; \
} \ } \
\ \
void name##_detach(name##_t **ptrp) { \ stat void name##_detach(name##_t **ptrp) { \
REQUIRE(ptrp != NULL && *ptrp != NULL); \ REQUIRE(ptrp != NULL && *ptrp != NULL); \
name##_t *ptr = *ptrp; \ name##_t *ptr = *ptrp; \
*ptrp = NULL; \ *ptrp = NULL; \
name##_unref(ptr); \ name##_unref(ptr); \
} }
#define ISC_REFCOUNT_IMPL(name, destroy) \
ISC__REFCOUNT_IMPL(name, destroy, ISC_REFCOUNT_BLANK)
#define ISC_REFCOUNT_STATIC_IMPL(name, destroy) \
ISC__REFCOUNT_IMPL(name, destroy, static inline)
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS