Files
hakmem/core/box/tiny_unified_lifo_box.h

122 lines
3.5 KiB
C
Raw Normal View History

// ============================================================================
// 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 <stdint.h>
#include <assert.h>
#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