Add debug functions
This commit is contained in:
@ -250,7 +250,7 @@ end:
|
||||
* @param refs Where to store the refs
|
||||
* @return True on success
|
||||
*/
|
||||
static inline bool obj_held_refs(RefcountContext *ctx, void *obj,
|
||||
static inline bool obj_held_refs(const RefcountContext *ctx, void *obj,
|
||||
RefcountList **refs) {
|
||||
if (ctx->held_refs_callback) {
|
||||
return ctx->held_refs_callback(obj, refs, ctx->user_data);
|
||||
@ -843,3 +843,48 @@ bool refcount_context_remove_destructor(const RefcountContext *ctx, void *obj,
|
||||
unlock_entry_mtx(ENTRY);
|
||||
return success;
|
||||
}
|
||||
|
||||
// Debug Functions
|
||||
|
||||
/**
|
||||
* Count all instances of a target object by walking the references of some root
|
||||
* object. This is for debug purposes only. The root is not included in the
|
||||
* count (as in, if `obj == target`, it will not be counted).
|
||||
* @param ctx The #RefcountContext
|
||||
* @param obj The root object
|
||||
* @param target The object to look for
|
||||
* @return The number of times the target appeared in the reference tree of the
|
||||
* root
|
||||
*/
|
||||
uint64_t refcount_debug_context_count_object(const RefcountContext *ctx,
|
||||
void *obj, void *target) {
|
||||
static const HTTableFunctions SEEN_FNS = {
|
||||
.destroy_key = NULL,
|
||||
.destroy_value = NULL,
|
||||
.equal = ht_intptr_equal_callback,
|
||||
.hash = ht_intptr_hash_callback,
|
||||
.user_data = NULL,
|
||||
};
|
||||
if (!obj) {
|
||||
return 0;
|
||||
}
|
||||
RefcountList *queue = NULL;
|
||||
obj_held_refs(ctx, obj, &queue);
|
||||
uint64_t total_count = 0;
|
||||
HTTable *seen = ht_new(&SEEN_FNS, &ctx->ht_alloc, NULL);
|
||||
while (queue) {
|
||||
void *cur = queue->data;
|
||||
queue = refcount_list_pop_full(queue, NULL, &ctx->alloc);
|
||||
// count NULL
|
||||
if (cur == target) {
|
||||
++total_count;
|
||||
}
|
||||
// but don't try to descend into it
|
||||
if (cur && !ht_has(seen, cur)) {
|
||||
ht_insert(seen, cur, NULL);
|
||||
obj_held_refs(ctx, cur, &queue);
|
||||
}
|
||||
}
|
||||
ht_free(seen);
|
||||
return total_count;
|
||||
}
|
||||
|
Reference in New Issue
Block a user