#ifndef TINY_DEBUG_H #define TINY_DEBUG_H #if !HAKMEM_BUILD_RELEASE #include #include #include #include "hakmem_tiny_superslab.h" #include "hakmem_tiny.h" static inline int tiny_alloc_debug_enabled(void) { static int g_debug = -1; if (__builtin_expect(g_debug == -1, 0)) { const char* e = getenv("HAKMEM_TINY_ALLOC_DEBUG"); g_debug = (e && atoi(e) != 0) ? 1 : 0; } return g_debug; } static inline void tiny_alloc_dump_tls_state(int class_idx, const char* tag, TinyTLSSlab* tls) { if (!tiny_alloc_debug_enabled()) return; fprintf(stderr, "[ALLOC-DBG:%s] class=%d tls_ss=%p slab_idx=%u meta=%p slab_base=%p\n", tag ? tag : "?", class_idx, (void*)tls->ss, (unsigned)tls->slab_idx, (void*)tls->meta, (void*)tls->slab_base); SuperSlab* ss = tls->ss; if (!(ss && ss->magic == SUPERSLAB_MAGIC)) { fprintf(stderr, " tls_ss invalid: ss=%p magic=0x%llx\n", (void*)ss, ss ? (unsigned long long)ss->magic : 0ull); return; } int cap = ss_slabs_capacity(ss); fprintf(stderr, " ss active_slabs=%u cap=%d bitmap=0x%08x total_active=%u ref=%u\n", ss->active_slabs, cap, ss->slab_bitmap, atomic_load_explicit(&ss->total_active_blocks, memory_order_relaxed), atomic_load_explicit(&ss->refcount, memory_order_relaxed)); int limit = (cap < 6) ? cap : 6; for (int i = 0; i < limit; i++) { uint32_t mask = 1u << i; TinySlabMeta* meta = &ss->slabs[i]; fprintf(stderr, " slab%02d active=%d used=%u cap=%u freelist=%p owner=%u class=%u\n", i, (ss->slab_bitmap & mask) ? 1 : 0, (unsigned)meta->used, (unsigned)meta->capacity, meta->freelist, meta->owner_tid_low, meta->class_idx); } } #else // HAKMEM_BUILD_RELEASE // No-op stubs for release builds static inline int tiny_alloc_debug_enabled(void) { return 0; } static inline void tiny_alloc_dump_tls_state(int class_idx, const char* tag, TinyTLSSlab* tls) { (void)class_idx; (void)tag; (void)tls; // No-op in release builds } #endif // !HAKMEM_BUILD_RELEASE #endif // TINY_DEBUG_H