// smallobject_cold_iface_mid_v3.c // Phase v11a-2: Cold interface implementation for MID v3.5 #include #include #include "box/smallobject_cold_iface_mid_v3_box.h" #include "box/smallobject_stats_mid_v3_box.h" #include "box/smallobject_mid_v35_geom_box.h" // Phase MID-V35-HOTPATH-OPT-1: geometry SSOT #include "box/mid_v35_hotpath_env_box.h" // Phase MID-V35-HOTPATH-OPT-1: Step 1-3 ENV gates #include "tiny_region_id.h" // For tiny_region_id_write_header // SmallPageMeta is defined in smallobject_segment_mid_v3_box.h #include "box/smallobject_segment_mid_v3_box.h" // ============================================================================ // TLS Segment Management // ============================================================================ // Thread-local segment (simplified for v11a-2) static __thread SmallSegment_MID_v3 *tls_mid_segment = NULL; // ============================================================================ // Helper: class_idx to slots // ============================================================================ // Phase MID-V35-HOTPATH-OPT-1: Use geom_box as Single Source of Truth // See: core/box/smallobject_mid_v35_geom_box.h // (Removed local class_idx_to_slots() which had wrong C6 value: 102 instead of 128) // ============================================================================ // Cold Interface Implementation // ============================================================================ SmallPageMeta_MID_v3* small_cold_mid_v3_refill_page(uint32_t class_idx) { // Ensure TLS segment exists if (!tls_mid_segment) { tls_mid_segment = small_segment_mid_v3_create(); if (!tls_mid_segment) { return NULL; } } // Try to take a page from the free stack void *page_ptr = small_segment_mid_v3_take_page(tls_mid_segment, class_idx); if (!page_ptr) { // No free pages available // In full implementation, would allocate new segment here // For v11a-2: just return NULL return NULL; } // Get page metadata SmallPageMeta_MID_v3 *page = small_segment_mid_v3_get_page_meta( tls_mid_segment, page_ptr ); if (!page) { // Failed to get metadata return NULL; } // Initialize page for allocation page->class_idx = class_idx; page->capacity = mid_v35_slots_per_page(class_idx); page->alloc_count = 0; page->free_count = 0; // Phase MID-V35-HOTPATH-OPT-1 Step 1: Header prefill at refill boundary // When enabled, write all headers now so hot path can skip per-alloc header writes if (mid_v35_header_prefill_enabled()) { size_t slot_size = mid_v35_slot_size(class_idx); uint32_t cap = page->capacity; uint8_t *p = (uint8_t*)page_ptr; for (uint32_t i = 0; i < cap; i++) { tiny_region_id_write_header(p + i * slot_size, class_idx); } } return page; } void small_cold_mid_v3_retire_page(SmallPageMeta_MID_v3 *page) { if (!page || !page->segment) { return; } SmallSegment_MID_v3 *seg = (SmallSegment_MID_v3*)page->segment; // Calculate free hit ratio (in basis points, 0-10000) uint32_t free_hit_ratio_bps = 0; if (page->alloc_count > 0) { free_hit_ratio_bps = (page->free_count * 10000) / page->alloc_count; } // Publish stats to StatsBox SmallPageStatsMID_v3 stat = { .class_idx = page->class_idx, .total_allocations = page->alloc_count, .total_frees = page->free_count, .page_alloc_count = page->capacity, .free_hit_ratio_bps = free_hit_ratio_bps, .lifetime_ns = 0 // Not tracking lifetime in v11a-2 }; small_stats_mid_v3_publish(&stat); // Reset page metadata uint8_t old_class_idx = page->class_idx; page->class_idx = 0xFF; // Mark as unassigned page->alloc_count = 0; page->free_count = 0; // Return page to free stack small_segment_mid_v3_release_page(seg, page->ptr, old_class_idx); }