/* buddy_debug.c — ASCII visualization for buddy allocator Included from runtime.c only when DUMP_BUDDY is defined. */ static void buddy_dump(BuddyPool *pool, const char *op, uint8_t *block, uint8_t order) { if (!pool || !pool->base) return; int levels = pool->max_order - BUDDY_MIN_ORDER + 1; /* Bitmap: one byte per min-block slot */ size_t num_slots = pool->total_size >> BUDDY_MIN_ORDER; /* Dynamic VLA — pool sizes vary now */ uint8_t *bitmap = alloca(num_slots); memset(bitmap, 0, num_slots); /* 0 = allocated */ /* Walk all free lists and mark free slots */ for (int i = 0; i < levels; i++) { for (BuddyBlock *p = pool->free_lists[i]; p; p = p->next) { size_t off = (uint8_t *)p - pool->base; size_t slot = off >> BUDDY_MIN_ORDER; size_t count = 1ULL << i; /* number of min-block slots in this block */ for (size_t s = 0; s < count && (slot + s) < num_slots; s++) bitmap[slot + s] = 1; } } /* Render 64-char ASCII bar */ size_t slots_per_char = num_slots / 64; if (slots_per_char == 0) slots_per_char = 1; char bar[65]; size_t total_free_slots = 0; for (int c = 0; c < 64; c++) { size_t base_slot = c * slots_per_char; size_t free_count = 0; for (size_t s = 0; s < slots_per_char && (base_slot + s) < num_slots; s++) { if (bitmap[base_slot + s]) free_count++; } total_free_slots += free_count; /* Majority vote: if more than half are free, show free */ bar[c] = (free_count > slots_per_char / 2) ? '.' : '#'; } bar[64] = '\0'; size_t blk_offset = block - pool->base; size_t blk_size = 1ULL << order; size_t total_free = total_free_slots << BUDDY_MIN_ORDER; size_t total_alloc = pool->total_size - total_free; fprintf(stderr, "buddy %s: pool %zuKB order %u (%zuKB) @ +%zuKB allocs=%u\n", op, pool->total_size / 1024, order, blk_size / 1024, blk_offset / 1024, pool->alloc_count); fprintf(stderr, " [%s]\n", bar); fprintf(stderr, " alloc: %zuKB free: %zuKB total: %zuKB\n", total_alloc / 1024, total_free / 1024, pool->total_size / 1024); /* Print free list population */ fprintf(stderr, " free lists:"); for (int i = 0; i < levels; i++) { int count = 0; for (BuddyBlock *p = pool->free_lists[i]; p; p = p->next) count++; if (count > 0) fprintf(stderr, " o%d:%d", i + BUDDY_MIN_ORDER, count); } fprintf(stderr, "\n"); }