#ifndef HAKMEM_TINY_MINI_MAG_H #define HAKMEM_TINY_MINI_MAG_H #include #include // ============================================================================ // Page Mini-Magazine: Fast LIFO Cache (Data Plane) // ============================================================================ // // Purpose: Provide O(1) allocation/free on page level // Design: Intrusive LIFO free-list (mimalloc-style) // Cost: 1-2 ns per operation (vs 5-6 ns bitmap scan) // // Key Insight: Free blocks store next-pointer in first 8 bytes // No separate metadata needed (zero overhead) // // ============================================================================ // ---------------------------------------------------------------------------- // Intrusive LIFO Block // ---------------------------------------------------------------------------- typedef struct MiniMagBlock { struct MiniMagBlock* next; // Next free block in LIFO stack } MiniMagBlock; // ---------------------------------------------------------------------------- // Mini-Magazine Metadata // ---------------------------------------------------------------------------- typedef struct { MiniMagBlock* head; // LIFO stack head (NULL if empty) uint16_t count; // Current item count [0, capacity] uint16_t capacity; // Maximum items (16-32 typical) } PageMiniMag; // ============================================================================ // Core Operations (Always Inlined for Speed) // ============================================================================ // ---------------------------------------------------------------------------- // Pop from Mini-Magazine (Fast Path: 1-2 ns) // ---------------------------------------------------------------------------- // // Returns: Pointer to free block, or NULL if empty // Cost: 1-2 ns (two pointer operations in L1 cache) // static inline void* mini_mag_pop(PageMiniMag* mag) __attribute__((always_inline)); static inline void* mini_mag_pop(PageMiniMag* mag) { MiniMagBlock* b = mag->head; if (!b) return NULL; // Empty // Pop from LIFO stack mag->head = b->next; mag->count--; return (void*)b; } // ---------------------------------------------------------------------------- // Push to Mini-Magazine (Fast Path: 1-2 ns) // ---------------------------------------------------------------------------- // // Returns: 1 on success, 0 if magazine is full // Cost: 1-2 ns (two pointer operations + count check) // static inline int mini_mag_push(PageMiniMag* mag, void* ptr) __attribute__((always_inline)); static inline int mini_mag_push(PageMiniMag* mag, void* ptr) { if (mag->count >= mag->capacity) return 0; // Full // Push to LIFO stack (intrusive next-pointer) MiniMagBlock* b = (MiniMagBlock*)ptr; b->next = mag->head; mag->head = b; mag->count++; return 1; } // ---------------------------------------------------------------------------- // Query Operations // ---------------------------------------------------------------------------- // Check if mini-magazine is empty static inline int mini_mag_is_empty(const PageMiniMag* mag) { return mag->count == 0; } // Check if mini-magazine is full static inline int mini_mag_is_full(const PageMiniMag* mag) { return mag->count >= mag->capacity; } // Get available space static inline int mini_mag_space(const PageMiniMag* mag) { return mag->capacity - mag->count; } // ============================================================================ // Initialization // ============================================================================ // Initialize mini-magazine (call on slab creation) static inline void mini_mag_init(PageMiniMag* mag, uint16_t capacity) { mag->head = NULL; mag->count = 0; mag->capacity = capacity; } // Reset mini-magazine (clear all items without freeing) static inline void mini_mag_reset(PageMiniMag* mag) { mag->head = NULL; mag->count = 0; } // ============================================================================ // Design Notes // ============================================================================ // // 1. LIFO Order (Temporal Locality): // - Most recently freed block = next allocated // - Excellent L1 cache hit rate (95%+) // - Hot blocks stay hot (cache-friendly) // // 2. Intrusive Design (Zero Overhead): // - Next-pointer stored in free block itself // - No separate metadata array needed // - Memory overhead: 0 bytes // // 3. Thread Safety: // - Owner-only access (no locks needed) // - Thread-local page has thread-local mini-magazine // - Remote frees go to separate MPSC queue // // 4. Capacity Tuning: // - Small (8-16): Lower memory, frequent refills // - Medium (16-32): Balanced (recommended) // - Large (32-64): Fewer refills, more memory // // 5. Integration with Bitmap: // - Mini-magazine = Data plane (fast path) // - Bitmap = Control plane (truth) // - Batch refill amortizes bitmap scan cost // // ============================================================================ #endif // HAKMEM_TINY_MINI_MAG_H