// ============================================================================ // Phase 15 v1: Tiny Unified LIFO Box (L1) - LIFO Stack Operations // ============================================================================ // // Purpose: LIFO (stack) operations for UnifiedCache // // Design: docs/analysis/PHASE15_UNIFIEDCACHE_LIFO_1_DESIGN.md // // Strategy: // - Reuse existing TinyUnifiedCache.slots[] array // - Treat `tail` as stack top (depth) // - Treat `head` as unused (always 0) // - No wrap-around (`mask` unused) // // Invariants: // - 0 <= tail <= capacity (stack depth) // - head == 0 (unused in LIFO mode) // - LIFO and FIFO modes are mutually exclusive // // API: // unified_cache_try_pop_lifo(class_idx) -> void* (BASE or NULL) // unified_cache_try_push_lifo(class_idx, base) -> int (1=success, 0=full) // // Safety: // - Debug: assert tail <= capacity // - Release: fast path, no checks // // ============================================================================ #ifndef TINY_UNIFIED_LIFO_BOX_H #define TINY_UNIFIED_LIFO_BOX_H #include #include #include "../hakmem_build_flags.h" #include "../hakmem_tiny_config.h" // TINY_NUM_CLASSES #include "../front/tiny_unified_cache.h" // TinyUnifiedCache #include "tiny_unified_lifo_env_box.h" // tiny_unified_lifo_enabled // ============================================================================ // LIFO Pop (Alloc Fast Path) // ============================================================================ // // Arguments: // class_idx - Tiny class index (0-7) // // Returns: // BASE pointer - Block from top of stack // NULL - Stack empty // // Side effects: // - Decrements tail (stack depth) // // LIFO semantics: // - Pop from top of stack (tail - 1) // - tail is "one past last element" (like vector.size()) // __attribute__((always_inline)) static inline void* unified_cache_try_pop_lifo(int class_idx) { extern __thread TinyUnifiedCache g_unified_cache[]; TinyUnifiedCache* cache = &g_unified_cache[class_idx]; // Empty check (tail == 0 means stack is empty) if (__builtin_expect(cache->tail == 0, 0)) { return NULL; // Empty } // Pop from top of stack (LIFO) void* base = cache->slots[--cache->tail]; // Debug: validate stack depth #if !HAKMEM_BUILD_RELEASE assert(cache->tail <= cache->capacity); #endif return base; // HIT (BASE pointer) } // ============================================================================ // LIFO Push (Free Fast Path) // ============================================================================ // // Arguments: // class_idx - Tiny class index (0-7) // base - BASE pointer to freed block // // Returns: // 1 - Block pushed to stack (success) // 0 - Stack full (overflow) // // Side effects: // - Increments tail (stack depth) // // LIFO semantics: // - Push to top of stack (tail) // - tail is "one past last element" // __attribute__((always_inline)) static inline int unified_cache_try_push_lifo(int class_idx, void* base) { extern __thread TinyUnifiedCache g_unified_cache[]; TinyUnifiedCache* cache = &g_unified_cache[class_idx]; // Full check (tail == capacity means stack is full) if (__builtin_expect(cache->tail >= cache->capacity, 0)) { return 0; // Full } // Push to top of stack (LIFO) cache->slots[cache->tail++] = base; // Debug: validate stack depth #if !HAKMEM_BUILD_RELEASE assert(cache->tail <= cache->capacity); #endif return 1; // SUCCESS } #endif // TINY_UNIFIED_LIFO_BOX_H