// capacity_box.c - Box Capacity Manager Implementation #include "capacity_box.h" #include "../tiny_adaptive_sizing.h" // TLSCacheStats, adaptive_sizing_init() #include "../hakmem_tiny.h" // g_tls_sll_count #include "../hakmem_tiny_config.h" // TINY_NUM_CLASSES, TINY_TLS_MAG_CAP #include "../hakmem_tiny_integrity.h" // HAK_CHECK_CLASS_IDX #include #include #include // ============================================================================ // Internal State // ============================================================================ // Initialization flag (atomic for thread-safety) static _Atomic int g_box_cap_initialized = 0; // External declarations (from adaptive_sizing and hakmem_tiny) extern __thread TLSCacheStats g_tls_cache_stats[TINY_NUM_CLASSES]; // TLS variable! extern __thread TinyTLSSLL g_tls_sll[TINY_NUM_CLASSES]; extern int g_sll_multiplier; // ============================================================================ // Box Capacity API Implementation // ============================================================================ void box_cap_init(void) { // Idempotent: only initialize once int expected = 0; if (atomic_compare_exchange_strong(&g_box_cap_initialized, &expected, 1)) { // First call: initialize adaptive sizing adaptive_sizing_init(); } // Already initialized or just initialized: safe to proceed } bool box_cap_is_initialized(void) { return atomic_load(&g_box_cap_initialized) != 0; } uint32_t box_cap_get(int class_idx) { // PRIORITY 1: Bounds check HAK_CHECK_CLASS_IDX(class_idx, "box_cap_get"); // Ensure initialized if (!box_cap_is_initialized()) { // Auto-initialize on first use (defensive) box_cap_init(); } // Compute SLL capacity using same logic as sll_cap_for_class() // This centralizes the capacity calculation(旧 g_sll_cap_override は削除済み)。 // Get base capacity from adaptive sizing uint32_t cap = g_tls_cache_stats[class_idx].capacity; // Apply class-specific multipliers if (class_idx <= 3) { // Hot classes: multiply by g_sll_multiplier uint32_t mult = (g_sll_multiplier > 0 ? (uint32_t)g_sll_multiplier : 1u); uint64_t want = (uint64_t)cap * (uint64_t)mult; if (want > (uint64_t)TINY_TLS_MAG_CAP) { cap = TINY_TLS_MAG_CAP; } else { cap = (uint32_t)want; } } else if (class_idx >= 4) { // Mid-large classes: halve capacity cap = (cap > 1u ? (cap / 2u) : 1u); } return cap; } bool box_cap_has_room(int class_idx, uint32_t n) { // PRIORITY 1: Bounds check HAK_CHECK_CLASS_IDX(class_idx, "box_cap_has_room"); uint32_t cap = box_cap_get(class_idx); uint32_t used = g_tls_sll[class_idx].count; // Check if adding N would exceed capacity if (used >= cap) return false; uint32_t avail = cap - used; return (n <= avail); } uint32_t box_cap_avail(int class_idx) { // PRIORITY 1: Bounds check HAK_CHECK_CLASS_IDX(class_idx, "box_cap_avail"); uint32_t cap = box_cap_get(class_idx); uint32_t used = g_tls_sll[class_idx].count; if (used >= cap) return 0; return (cap - used); } void box_cap_update(int class_idx, uint32_t new_cap) { // PRIORITY 1: Bounds check HAK_CHECK_CLASS_IDX(class_idx, "box_cap_update"); // Ensure initialized if (!box_cap_is_initialized()) { box_cap_init(); } // Clamp to max if (new_cap > TINY_TLS_MAG_CAP) { new_cap = TINY_TLS_MAG_CAP; } // Update adaptive sizing stats g_tls_cache_stats[class_idx].capacity = new_cap; }