AllocatorFootprintBytes
Description
Total committed bytes the allocator currently holds: live user regions + retained / cached regions + the allocator’s own bookkeeping mmaps. The honest “what does the kernel think this allocator costs” number, distinct from AllocatorBytesInUse(a) which only counts live user bytes. Maintained as an inline counter on the base, kept in sync by the internal page-map shim (every typed backend passes its &base so accounting flows without per-call bookkeeping at the typed layer). Same ((void)0, ...) accessor shape as the stats; ALLOCATOR_OF performs the typed -> base cast via _Generic without dispatching, so the macro compiles down to a direct field load. No function call, no vtable.
Usage example (Cross-references)
Usage examples (Cross-references)
uint64_t bench_footprint_bytes(void) {
if (!g_page_live) return 0;
return (uint64_t)AllocatorFootprintBytes(&g_page);
} // is the exact OS-page footprint, no estimation.
if (!g_arena_live) return 0;
return (uint64_t)AllocatorFootprintBytes(&g_arena);
} if (!g_heap_typed)
return 0;
return (uint64_t)AllocatorFootprintBytes(g_heap_typed);
}
uint64_t bench_footprint_bytes(void) {
if (g_mode == MODE_HEAP) return (uint64_t)AllocatorFootprintBytes(&g_heap);
if (g_mode == MODE_SLAB) return (uint64_t)AllocatorFootprintBytes(&g_slab);
if (g_mode == MODE_PAGE) return (uint64_t)AllocatorFootprintBytes(&g_page); uint64_t bench_footprint_bytes(void) {
if (g_mode == MODE_HEAP) return (uint64_t)AllocatorFootprintBytes(&g_heap);
if (g_mode == MODE_SLAB) return (uint64_t)AllocatorFootprintBytes(&g_slab);
if (g_mode == MODE_PAGE) return (uint64_t)AllocatorFootprintBytes(&g_page);
return 0; if (g_mode == MODE_HEAP) return (uint64_t)AllocatorFootprintBytes(&g_heap);
if (g_mode == MODE_SLAB) return (uint64_t)AllocatorFootprintBytes(&g_slab);
if (g_mode == MODE_PAGE) return (uint64_t)AllocatorFootprintBytes(&g_page);
return 0;
} ok = false;
}
if (AllocatorFootprintBytes(&alloc) != 0) {
WriteFmt("init Footprint != 0\n");
ok = false; }
// Live footprint is at least p1 + p2; descriptor table adds more.
size foot_with_two = AllocatorFootprintBytes(&alloc);
if (foot_with_two < page + page * 2) {
WriteFmt("foot_with_two={} want >= {}\n", (u64)foot_with_two, (u64)(page + page * 2)); // Footprint includes descriptor table grow on free side, so it
// can be >= the live-only baseline. Must NOT shrink.
size foot_after_free_p1 = AllocatorFootprintBytes(&alloc);
if (foot_after_free_p1 < foot_with_two) {
WriteFmt("foot shrank after retention: {} < {}\n", (u64)foot_after_free_p1, (u64)foot_with_two); ok = false;
}
if (AllocatorFootprintBytes(&alloc) < foot_with_two) {
WriteFmt("foot shrank after all-free\n");
ok = false; ok = false;
}
if (AllocatorFootprintBytes(&alloc) != 0) {
WriteFmt("post-deinit Footprint != 0\n");
ok = false;
Last updated on