/** * mid_free_route_box.h * * Box: Mid Free Route Box * Responsibility: Route Mid MT allocations to correct free path * Contract: Try Mid MT registry lookup, return success/failure * * Part of Phase 5-Step2 fix for 19x free() slowdown * * Problem: * - Mid MT allocator registers chunks in MidGlobalRegistry * - Free path searches Pool's mid_desc registry (different registry!) * - Result: 100% lookup failure → 4x cascading lookups → 19x slower * * Solution: * - Add Mid MT registry lookup BEFORE Pool registry lookup * - Route directly to mid_mt_free() if found * - Fall through to existing path if not found * * Performance Impact: * - Before: 1.42 M ops/s (19x slower than system malloc) * - After: 14-21 M ops/s (Option B quick fix, 10-15x improvement) * * Created: 2025-11-29 (Phase 5-Step2 Mid MT Gap Fix) */ #ifndef MID_FREE_ROUTE_BOX_H #define MID_FREE_ROUTE_BOX_H #include "../hakmem_mid_mt.h" #include #ifdef __cplusplus extern "C" { #endif // ============================================================================ // Box Contract: Mid MT Free Routing // ============================================================================ /** * mid_free_route_try - Try Mid MT free path first * * @param ptr Pointer to free * @return true if handled by Mid MT, false to fall through * * Phase 6-B: Header-based detection (lock-free!) * * Box Responsibilities: * 1. Read MidMTHeader from ptr - sizeof(MidMTHeader) * 2. Check magic number (0xAB42) * 3. If valid: Call mid_mt_free() and return true * 4. If invalid: Return false (let existing path handle it) * * Box Guarantees: * - Zero side effects if returning false * - Correct free if returning true * - Thread-safe (lock-free header read) * * Performance: * - Before (Phase 5): O(log N) registry lookup + mutex = ~50 cycles (13.98% CPU) * - After (Phase 6-B): O(1) header read + magic check = ~2 cycles (0.01% CPU) * - Expected improvement: +17-27% throughput * * Usage Example: * void free(void* ptr) { * if (mid_free_route_try(ptr)) return; // Mid MT handled * // Fall through to existing free path... * } */ __attribute__((always_inline)) static inline bool mid_free_route_try(void* ptr) { if (!ptr) return false; // NULL ptr, not Mid MT // Phase 6-B: Read header for O(1) detection (no mutex!) void* block = (uint8_t*)ptr - sizeof(MidMTHeader); MidMTHeader* hdr = (MidMTHeader*)block; // Check magic number to identify Mid MT allocation if (hdr->magic == MID_MT_MAGIC) { // Valid Mid MT allocation, route to mid_mt_free() // Pass block_size from header (no size needed from caller!) mid_mt_free(ptr, hdr->block_size); return true; // Handled } // Not a Mid MT allocation, fall through to existing path return false; } // ============================================================================ // Box Observability (Debug/Profiling) // ============================================================================ #if MID_DEBUG /** * mid_free_route_stats - Print Mid Free Route Box statistics * * Only available in debug builds (MID_DEBUG=1) * Tracks hit/miss rates for performance analysis */ void mid_free_route_stats(void); #endif #ifdef __cplusplus } #endif #endif // MID_FREE_ROUTE_BOX_H