void pr_pool_debug_memory(void (*debugf)(const char *, ...)) { if (debugf == NULL) { debugf = pool_printf; } debugf("Memory pool allocation:"); debugf("Total %lu bytes allocated", walk_pools(permanent_pool, 0, debugf)); debug_pool_info(debugf); }
/* Walk all pools, starting with top level permanent pool, displaying a * tree. */ static long walk_pools(pool *p, int level, void (*debugf)(const char *, ...)) { char _levelpad[80] = ""; long total = 0; if (p == NULL) { return 0; } if (level > 1) { memset(_levelpad, ' ', sizeof(_levelpad)-1); if ((level - 1) * 3 >= sizeof(_levelpad)) { _levelpad[sizeof(_levelpad)-1] = 0; } else { _levelpad[(level - 1) * 3] = '\0'; } } /* The emitted message is: * * <pool-tag> [pool-ptr] (n B, m L, r P) * * where n is the number of bytes (B), m is the number of allocated blocks * in the pool list (L), and r is the number of sub-pools (P). */ for (; p; p = p->sub_next) { total += bytes_in_block_list(p->first); if (level == 0) { debugf("%s [%p] (%lu B, %lu L, %u P)", p->tag ? p->tag : "<unnamed>", p, bytes_in_block_list(p->first), blocks_in_block_list(p->first), subpools_in_pool(p)); } else { debugf("%s + %s [%p] (%lu B, %lu L, %u P)", _levelpad, p->tag ? p->tag : "<unnamed>", p, bytes_in_block_list(p->first), blocks_in_block_list(p->first), subpools_in_pool(p)); } /* Recurse */ if (p->sub_pools) { total += walk_pools(p->sub_pools, level+1, debugf); } } return total; }