// hakmem_tiny_smallmag.inc.h // Layer 2: TLS Small Magazine (128 items, all classes) // // Purpose: Fast TLS cache with L1 locality (5-10 instructions/op) // Design: Simple stack-based magazine, index-only operations // // Part of 3-layer architecture simplification (2025-11-01) // Based on ChatGPT Pro UltraThink recommendations #ifndef HAKMEM_TINY_SMALLMAG_INC_H #define HAKMEM_TINY_SMALLMAG_INC_H // likely/unlikely macros #ifndef likely #define likely(x) __builtin_expect(!!(x), 1) #endif #ifndef unlikely #define unlikely(x) __builtin_expect(!!(x), 0) #endif // ============================================================================ // Data Structure // ============================================================================ #define TINY_SMALL_MAG_CAP 2048 // Test: same as old TLS Magazine typedef struct { void* items[TINY_SMALL_MAG_CAP]; int top; // Stack pointer (number of items) } TinySmallMag; // Per-class small magazine (all classes) static __thread TinySmallMag g_tiny_small_mag[TINY_NUM_CLASSES]; // Initialization flag static __thread int g_tiny_small_mag_initialized = 0; // Env gate: HAKMEM_TINY_SMALL_MAG=0 disables this layer static inline int tiny_small_mag_enabled(void) { static int en = -1; if (__builtin_expect(en == -1, 0)) { const char* e = getenv("HAKMEM_TINY_SMALL_MAG"); en = (e && *e == '0') ? 0 : 1; // default ON } return en; } // ============================================================================ // Initialization // ============================================================================ static __attribute__((unused)) void tiny_small_mag_init(void) { if (g_tiny_small_mag_initialized) return; if (!tiny_small_mag_enabled()) { g_tiny_small_mag_initialized = 1; return; } for (int i = 0; i < TINY_NUM_CLASSES; i++) { g_tiny_small_mag[i].top = 0; } g_tiny_small_mag_initialized = 1; } // ============================================================================ // Layer 2: Fast magazine pop/push (5-10 instructions/op) // ============================================================================ __attribute__((always_inline)) static inline void* small_mag_pop(int class_idx) { if (!tiny_small_mag_enabled()) return NULL; TinySmallMag* mag = &g_tiny_small_mag[class_idx]; int t = mag->top; if (likely(t > 0)) { mag->top = t - 1; return mag->items[t - 1]; } return NULL; // Empty, fallback to Layer 3 } __attribute__((always_inline)) static inline int small_mag_push(int class_idx, void* ptr) { if (!tiny_small_mag_enabled()) return 0; TinySmallMag* mag = &g_tiny_small_mag[class_idx]; int t = mag->top; if (likely(t < TINY_SMALL_MAG_CAP)) { mag->items[t] = ptr; mag->top = t + 1; return 1; } return 0; // Full, drain to Layer 3 } // ============================================================================ // Batch operations (for refill/drain from Layer 3) // ============================================================================ // Batch push: refill magazine from slab/large-mag // Returns number of items pushed static __attribute__((unused)) int small_mag_batch_push(int class_idx, void** items, int count) { if (!tiny_small_mag_enabled()) return 0; TinySmallMag* mag = &g_tiny_small_mag[class_idx]; int space = TINY_SMALL_MAG_CAP - mag->top; int to_push = (count < space) ? count : space; for (int i = 0; i < to_push; i++) { mag->items[mag->top + i] = items[i]; } mag->top += to_push; return to_push; } // Batch pop: drain magazine to large-mag/slab // Returns number of items popped static __attribute__((unused)) int small_mag_batch_pop(int class_idx, void** out_items, int max_count) { if (!tiny_small_mag_enabled()) return 0; TinySmallMag* mag = &g_tiny_small_mag[class_idx]; int to_pop = (mag->top < max_count) ? mag->top : max_count; for (int i = 0; i < to_pop; i++) { out_items[i] = mag->items[mag->top - 1 - i]; } mag->top -= to_pop; return to_pop; } // ============================================================================ // Utility functions // ============================================================================ static inline int small_mag_is_empty(int class_idx) { if (!tiny_small_mag_enabled()) return 1; return g_tiny_small_mag[class_idx].top == 0; } static inline int small_mag_is_full(int class_idx) { if (!tiny_small_mag_enabled()) return 0; return g_tiny_small_mag[class_idx].top >= TINY_SMALL_MAG_CAP; } static inline int small_mag_count(int class_idx) { if (!tiny_small_mag_enabled()) return 0; return g_tiny_small_mag[class_idx].top; } // Reset magazine (e.g., thread shutdown, drain all to slab) static void small_mag_reset(int class_idx) { g_tiny_small_mag[class_idx].top = 0; } static __attribute__((unused)) void small_mag_reset_all(void) { for (int i = 0; i < TINY_NUM_CLASSES; i++) { small_mag_reset(i); } } #endif // HAKMEM_TINY_SMALLMAG_INC_H