Files
hakmem/core/smallobject_cold_iface_mid_v3.c
Moe Charm (CI) d5ffb3eeb2 Fix MID v3.5 activation bugs: policy loop + malloc recursion
Two critical bugs fixed:

1. Policy snapshot infinite loop (smallobject_policy_v7.c):
   - Condition `g_policy_v7_version == 0` caused reinit on every call
   - Fixed via CAS to set global version to 1 after first init

2. Malloc recursion (smallobject_segment_mid_v3.c):
   - Internal malloc() routed back through hakmem → MID v3.5 → segment
     creation → malloc → infinite recursion / stack overflow
   - Fixed by using mmap() directly for internal allocations:
     - Segment struct, pages array, page metadata block

Performance results (bench_random_mixed 257-512B):
- Baseline (LEGACY): 34.0M ops/s
- MID_V35 ON (C6):   35.8M ops/s
- Improvement:       +5.1% ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 07:12:24 +09:00

107 lines
3.3 KiB
C

// smallobject_cold_iface_mid_v3.c
// Phase v11a-2: Cold interface implementation for MID v3.5
#include <stdlib.h>
#include <stdio.h>
#include "box/smallobject_cold_iface_mid_v3_box.h"
#include "box/smallobject_stats_mid_v3_box.h"
// 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
// ============================================================================
static uint32_t class_idx_to_slots(uint32_t class_idx) {
switch (class_idx) {
case 5: return 170; // C5: 257-384B
case 6: return 102; // C6: 385-640B
case 7: return 64; // C7: 641-1024B
default: return 0;
}
}
// ============================================================================
// 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 = class_idx_to_slots(class_idx);
page->alloc_count = 0;
page->free_count = 0;
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);
}