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>
107 lines
3.3 KiB
C
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);
|
|
}
|