dns_qpkey_t ascii;
} item[256 * 256 / 4];
-static void
+static uint32_t
fuzz_attach(void *ctx, void *pval, uint32_t ival) {
assert(ctx == NULL);
assert(pval == &item[ival]);
- item[ival].refcount++;
+ return (item[ival].refcount++);
}
-static void
+static uint32_t
fuzz_detach(void *ctx, void *pval, uint32_t ival) {
assert(ctx == NULL);
assert(pval == &item[ival]);
- item[ival].refcount--;
+ assert(item[ival].refcount > 0);
+ return (item[ival].refcount--);
}
static size_t
* The `attach` and `detach` methods adjust reference counts on value
* objects. They support copy-on-write and safe memory reclamation
* needed for multi-version concurrency. The methods are only called
- * when the `dns_qpmulti_t` mutex is held, so they only need to use
- * atomic ops if the refcounts are used by code other than the qp-trie.
+ * when the `dns_qpmulti_t` mutex is held. For tracing purposes, they
+ * should return the same value as `isc_refcount_increment()` or
+ * `isc_refcount_decrement()`, respectively
*
* Note: When a value object reference count is greater than one, the
* object is in use by concurrent readers so it must not be modified. A
* readable identifier into `buf` which has max length `size`.
*/
typedef struct dns_qpmethods {
- void (*attach)(void *uctx, void *pval, uint32_t ival);
- void (*detach)(void *uctx, void *pval, uint32_t ival);
+ uint32_t (*attach)(void *uctx, void *pval, uint32_t ival);
+ uint32_t (*detach)(void *uctx, void *pval, uint32_t ival);
size_t (*makekey)(dns_qpkey_t key, void *uctx, void *pval,
uint32_t ival);
void (*triename)(void *uctx, char *buf, size_t size);
* method invocation helpers
*/
+#if 0
+
+#define attach_leaf(qp, n) \
+ do { \
+ uint32_t iv = leaf_ival(n); \
+ void *pv = leaf_pval(n); \
+ uint32_t r = qp->methods->attach(qp->uctx, pv, iv); \
+ fprintf(stderr, \
+ "%s:%u:%s():t%u qp %p node %p leaf %p %u " \
+ "(%u -> %u)\n", \
+ __FILE__, __LINE__, __func__, isc_tid(), qp, n, pv, \
+ iv, r, r + 1); \
+ } while (0)
+
+#define detach_leaf(qp, n) \
+ do { \
+ uint32_t iv = leaf_ival(n); \
+ void *pv = leaf_pval(n); \
+ uint32_t r = qp->methods->detach(qp->uctx, pv, iv); \
+ fprintf(stderr, \
+ "%s:%u:%s():t%u qp %p node %p leaf %p %u " \
+ "(%u -> %u)\n", \
+ __FILE__, __LINE__, __func__, isc_tid(), qp, n, pv, \
+ iv, r, r - 1); \
+ } while (0)
+
+#else
+
static inline void
attach_leaf(dns_qpreadable_t qpr, qp_node_t *n) {
dns_qpreader_t *qp = dns_qpreader(qpr);
qp->methods->detach(qp->uctx, leaf_pval(n), leaf_ival(n));
}
+#endif
+
static inline size_t
leaf_qpkey(dns_qpreadable_t qpr, qp_node_t *n, dns_qpkey_t key) {
dns_qpreader_t *qp = dns_qpreader(qpr);
dns_fixedname_t fixed;
} item[1024 * 1024];
-static void
+static uint32_t
item_check(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
assert(pval == &item[ival]);
+ return (1);
}
static size_t
return (dns_qpkey_fromname(key, &name));
}
-static void
+static uint32_t
smallname_attach(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
- isc_refcount_increment0(smallname_refcount(pval, ival));
+ return (isc_refcount_increment0(smallname_refcount(pval, ival)));
}
-static void
+static uint32_t
smallname_detach(void *ctx, void *pval, uint32_t ival) {
- if (isc_refcount_decrement(smallname_refcount(pval, ival)) == 1) {
+ uint32_t refs = isc_refcount_decrement(smallname_refcount(pval, ival));
+ if (refs == 1) {
isc_mem_free(ctx, pval);
}
+ return (refs);
}
static void
dns_qpkey_t key;
} *item;
-static void
+static uint32_t
item_refcount(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
UNUSED(pval);
UNUSED(ival);
+ return (1);
}
static size_t
dns_qpkey_t ascii;
} item[ITEM_COUNT];
-static void
+static uint32_t
item_attach(void *ctx, void *pval, uint32_t ival) {
- INSIST(ctx == NULL);
- INSIST(pval == &item[ival]);
- item[ival].refcount++;
+ assert_null(ctx);
+ assert_ptr_equal(pval, &item[ival]);
+ return (item[ival].refcount++);
}
-static void
+static uint32_t
item_detach(void *ctx, void *pval, uint32_t ival) {
assert_null(ctx);
assert_ptr_equal(pval, &item[ival]);
- item[ival].refcount--;
+ assert_int_not_equal(item[ival].refcount, 0);
+ return (item[ival].refcount--);
}
static size_t