// hakmem_tiny_query.c // Phase 2B-1: Query API // Extracted from hakmem_tiny.c (lines 4295-4346) #include #include #include #include "hakmem_tiny.h" #include "hakmem_tiny_config.h" // extern g_tiny_class_sizes #include "hakmem_tiny_query_api.h" #include "hakmem_tiny_superslab.h" #include "hakmem_super_registry.h" #include "hakmem_config.h" // External globals (defined in hakmem_tiny.c) extern int g_tiny_initialized; extern int g_use_superslab; // g_tiny_class_sizes is in hakmem_tiny.h (static const) // External functions extern TinySlab* hak_tiny_owner_slab(void* ptr); // hak_super_lookup is static inline in hakmem_super_registry.h int hak_tiny_is_managed(void* ptr) { if (!ptr || !g_tiny_initialized) return 0; // Phase 6.12.1: O(1) slab lookup via registry/list return hak_tiny_owner_slab(ptr) != NULL || hak_super_lookup(ptr) != NULL; } int hak_tiny_is_managed_superslab(void* ptr) { if (!ptr || !g_tiny_initialized) return 0; // Safety: Only check if g_use_superslab is enabled if (g_use_superslab) { SuperSlab* ss = hak_super_lookup(ptr); if (ss && ss->magic == SUPERSLAB_MAGIC) { // Phase 12: Use registry hit as "managed by SuperSlab" return 1; } } // Fallback to TinySlab check return hak_tiny_owner_slab(ptr) != NULL; } size_t hak_tiny_usable_size(void* ptr) { if (!ptr || !g_tiny_initialized) return 0; // Check SuperSlab first via registry (safe under direct link and LD) if (g_use_superslab) { SuperSlab* ss = hak_super_lookup(ptr); if (ss && ss->magic == SUPERSLAB_MAGIC) { // Phase 12: derive class from per-slab meta (no ss->size_class) void* base = (void*)((uint8_t*)ptr - 1); int slab_idx = slab_index_for(ss, base); if (slab_idx >= 0 && slab_idx < ss_slabs_capacity(ss)) { TinySlabMeta* meta = &ss->slabs[slab_idx]; int k = (meta->class_idx < TINY_NUM_CLASSES) ? (int)meta->class_idx : -1; if (k >= 0) { #if HAKMEM_TINY_HEADER_CLASSIDX size_t stride = g_tiny_class_sizes[k]; return (stride > 0) ? (stride - 1) : 0; #else return g_tiny_class_sizes[k]; #endif } } } } // Fallback: TinySlab owner lookup TinySlab* slab = hak_tiny_owner_slab(ptr); if (slab) { int k = slab->class_idx; if (k >= 0 && k < TINY_NUM_CLASSES) { // Phase E1-CORRECT: g_tiny_class_sizes = total size (stride) // Usable = stride - 1 (for 1-byte header) #if HAKMEM_TINY_HEADER_CLASSIDX size_t stride = g_tiny_class_sizes[k]; return (stride > 0) ? (stride - 1) : 0; #else return g_tiny_class_sizes[k]; #endif } } return 0; }