/* 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; }
static void debug_pool_info(void (*debugf)(const char *, ...)) { if (block_freelist) debugf("Free block list: %lu bytes", bytes_in_block_list(block_freelist)); else debugf("Free block list: empty"); debugf("%u count blocks allocated", stat_malloc); debugf("%u count blocks reused", stat_freehit); }
EP_API_EXPORT(long) ep_bytes_in_free_blocks(void) { return bytes_in_block_list(block_freelist); }
EP_API_EXPORT(long) ep_bytes_in_pool(tMemPool *p) { return bytes_in_block_list(p->first); }