Files
hakmem/core/box/carve_push_box.c

248 lines
8.8 KiB
C
Raw Normal View History

Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
// carve_push_box.c - Box Carve-And-Push Implementation
#include <stdio.h>
#include <stdlib.h>
#include <stdatomic.h>
#include "../hakmem_tiny.h" // MUST BE FIRST: Base types
#include "../tiny_tls.h" // TinyTLSSlab type definition
#include "../hakmem_tiny_config.h" // TINY_NUM_CLASSES
#include "../hakmem_tiny_superslab.h" // ss_active_add(), SuperSlab
#include "../hakmem_tiny_integrity.h" // HAK_CHECK_CLASS_IDX
#include "../tiny_region_id.h" // HEADER_MAGIC, HEADER_CLASS_MASK
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
#include "carve_push_box.h"
#include "capacity_box.h" // box_cap_has_room()
#include "tls_sll_box.h" // tls_sll_push()
#include "tiny_next_ptr_box.h" // tiny_next_write()
Bugfix: Add Header Box and fix Class 0/7 header handling (crash rate -50%) Root Cause Analysis: - tls_sll_box.h had hardcoded `class_idx != 7` checks - This incorrectly assumed only C7 uses offset=0 - But C0 (8B) also uses offset=0 (header overwritten by next pointer) - Result: C0 blocks had corrupted headers in TLS SLL → crash Architecture Fix: Header Box (Single Source of Truth) - Created core/box/tiny_header_box.h - Encapsulates "which classes preserve headers" logic - Delegates to tiny_nextptr.h (0x7E bitmask: C0=0, C1-C6=1, C7=0) - API: * tiny_class_preserves_header() - C1-C6 only * tiny_header_write_if_preserved() - Conditional write * tiny_header_validate() - Conditional validation * tiny_header_write_for_alloc() - Unconditional (alloc path) Bug Fixes (6 locations): - tls_sll_box.h:366 - push header restore (C1-C6 only; skip C0/C7) - tls_sll_box.h:560 - pop header validate (C1-C6 only; skip C0/C7) - tls_sll_box.h:700 - splice header restore head (C1-C6 only) - tls_sll_box.h:722 - splice header restore next (C1-C6 only) - carve_push_box.c:198 - freelist→TLS SLL header restore - hakmem_tiny_free.inc:78 - drain freelist header restore Impact: - Before: 23.8% crash rate (bench_random_mixed_hakmem) - After: 12% crash rate - Improvement: 49.6% reduction in crashes - Test: 88/100 runs successful (vs 76/100 before) Design Principles: - Eliminates hardcoded class_idx checks (class_idx != 7) - Single Source of Truth (tiny_nextptr.h → Header Box) - Type-safe API prevents future bugs - Future: Add lint to forbid direct header manipulation Remaining Work: - 12% crash rate still exists (likely different root cause) - Next: Investigate with core dump analysis 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:57:49 +09:00
#include "tiny_header_box.h" // Header Box: Single Source of Truth for header operations
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
#include "../tiny_refill_opt.h" // TinyRefillChain, trc_linear_carve()
#include "../tiny_box_geometry.h" // tiny_stride_for_class(), tiny_slab_base_for_geometry()
#include "c7_meta_used_counter_box.h"
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
// External declarations
extern __thread TinyTLSSlab g_tls_slabs[TINY_NUM_CLASSES];
extern __thread TinyTLSSLL g_tls_sll[TINY_NUM_CLASSES];
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
// ============================================================================
// Internal Helpers
// ============================================================================
// Rollback: return carved blocks to freelist
static void rollback_carved_blocks(int class_idx, TinySlabMeta* meta,
void* head, uint32_t count) {
// Walk the chain and prepend to freelist
void* node = head;
for (uint32_t i = 0; i < count && node; i++) {
void* next = tiny_next_read(class_idx, node);
// Prepend to freelist
tiny_next_write(class_idx, node, meta->freelist);
meta->freelist = node;
node = next;
}
// Rollback metadata counters
meta->carved = (uint16_t)((uint32_t)meta->carved - count);
meta->used = (uint16_t)((uint32_t)meta->used - count);
}
// ============================================================================
// Box Carve-Push API Implementation
// ============================================================================
uint32_t box_carve_and_push(int class_idx, uint32_t want) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_carve_and_push");
if (want == 0) return 0;
// Step 1: Check TLS SLL capacity
if (!box_cap_has_room(class_idx, want)) {
// Not enough room in TLS SLL
return 0;
}
// Step 2: Get TLS slab
TinyTLSSlab* tls = &g_tls_slabs[class_idx];
if (!tls->ss || !tls->meta) {
// No SuperSlab available
return 0;
}
TinySlabMeta* meta = tls->meta;
// Step 3: Check if slab has enough uncarved blocks
uint32_t available = (meta->capacity > meta->carved)
? (meta->capacity - meta->carved) : 0;
if (available < want) {
// Not enough uncarved blocks
// Note: Could try superslab_refill() here, but keeping it simple for now
return 0;
}
// Step 4: Get stride and slab base
size_t bs = tiny_stride_for_class(class_idx);
uint8_t* slab_base = tls->slab_base ? tls->slab_base
: tiny_slab_base_for_geometry(tls->ss, tls->slab_idx);
// Step 5: Carve blocks (builds a linked chain)
TinyRefillChain chain;
trc_linear_carve(slab_base, bs, meta, want, class_idx, &chain);
// Sanity check
if (chain.count != want) {
// Carve failed to produce expected count
// This should not happen, but handle defensively
#if !HAKMEM_BUILD_RELEASE
fprintf(stderr, "[BOX_CARVE_PUSH] WARN: carved %u blocks but expected %u\n",
chain.count, want);
#endif
// Rollback metadata (carved/used already updated by trc_linear_carve)
meta->carved = (uint16_t)((uint32_t)meta->carved - chain.count);
meta->used = (uint16_t)((uint32_t)meta->used - chain.count);
return 0;
}
// Step 6: Push all blocks to TLS SLL (with rollback on failure)
uint32_t sll_cap = box_cap_get(class_idx);
uint32_t pushed = 0;
void* node = chain.head;
for (uint32_t i = 0; i < want && node; i++) {
void* next = tiny_next_read(class_idx, node);
if (!tls_sll_push(class_idx, node, sll_cap)) {
// Push failed (SLL full or other error)
// Rollback: pop all pushed blocks and return to freelist
#if !HAKMEM_BUILD_RELEASE
fprintf(stderr, "[BOX_CARVE_PUSH] Push failed at block %u/%u, rolling back\n",
i, want);
#endif
// Pop the blocks we just pushed
Fix: TLS SLL double-free diagnostics - Add error handling and detection improvements Problem: workset=8192 crashes at 240K iterations with TLS SLL double-free: [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... already in SLL Investigation (Task agent): Identified 8 tls_sll_push() call sites and 3 high-risk areas: 1. HIGH: Carve-Push Rollback pop failures (carve_push_box.c) 2. MEDIUM: Splice partial orphaned nodes (tiny_refill_opt.h) 3. MEDIUM: Incomplete double-free scan - only 64 nodes (tls_sll_box.h) Fixes Applied: 1. core/box/carve_push_box.c (Lines 115-139) - Track pop_failed count during rollback - Log orphaned blocks: [BOX_CARVE_PUSH_ROLLBACK] warning - Helps identify when rollback leaves blocks in SLL 2. core/box/tls_sll_box.h (Lines 347-370) - Increase double-free scan: 64 → 256 nodes - Add scanned count to error: (scanned=%u/%u) - Catches orphaned blocks deeper in chain 3. core/tiny_refill_opt.h (Lines 135-166) - Enhanced splice partial logging - Abort in debug builds on orphaned nodes - Prevents silent memory leaks Test Results: Before: SEGV at 220K iterations After: SEGV at 240K iterations (improved detection) [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... (scanned=2/71) Impact: ✅ Early detection working (catches at position 2) ✅ Diagnostic capability greatly improved ⚠️ Root cause not yet resolved (deeper investigation needed) Status: Diagnostic improvements committed for further analysis Credit: Root cause analysis by Task agent (Explore) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 08:43:18 +09:00
uint32_t pop_failed = 0;
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
for (uint32_t j = 0; j < pushed; j++) {
void* popped;
if (tls_sll_pop(class_idx, &popped)) {
// Return to freelist
tiny_next_write(class_idx, popped, meta->freelist);
meta->freelist = popped;
Fix: TLS SLL double-free diagnostics - Add error handling and detection improvements Problem: workset=8192 crashes at 240K iterations with TLS SLL double-free: [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... already in SLL Investigation (Task agent): Identified 8 tls_sll_push() call sites and 3 high-risk areas: 1. HIGH: Carve-Push Rollback pop failures (carve_push_box.c) 2. MEDIUM: Splice partial orphaned nodes (tiny_refill_opt.h) 3. MEDIUM: Incomplete double-free scan - only 64 nodes (tls_sll_box.h) Fixes Applied: 1. core/box/carve_push_box.c (Lines 115-139) - Track pop_failed count during rollback - Log orphaned blocks: [BOX_CARVE_PUSH_ROLLBACK] warning - Helps identify when rollback leaves blocks in SLL 2. core/box/tls_sll_box.h (Lines 347-370) - Increase double-free scan: 64 → 256 nodes - Add scanned count to error: (scanned=%u/%u) - Catches orphaned blocks deeper in chain 3. core/tiny_refill_opt.h (Lines 135-166) - Enhanced splice partial logging - Abort in debug builds on orphaned nodes - Prevents silent memory leaks Test Results: Before: SEGV at 220K iterations After: SEGV at 240K iterations (improved detection) [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... (scanned=2/71) Impact: ✅ Early detection working (catches at position 2) ✅ Diagnostic capability greatly improved ⚠️ Root cause not yet resolved (deeper investigation needed) Status: Diagnostic improvements committed for further analysis Credit: Root cause analysis by Task agent (Explore) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 08:43:18 +09:00
} else {
// Pop failed - block remains orphaned in SLL!
pop_failed++;
#if !HAKMEM_BUILD_RELEASE
fprintf(stderr, "[BOX_CARVE_PUSH_ROLLBACK] Pop failed for block %u/%u (cls=%d)\n",
j, pushed, class_idx);
fprintf(stderr, "[BOX_CARVE_PUSH_ROLLBACK] Block orphaned in TLS SLL - potential double-free risk!\n");
#endif
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
}
}
Fix: TLS SLL double-free diagnostics - Add error handling and detection improvements Problem: workset=8192 crashes at 240K iterations with TLS SLL double-free: [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... already in SLL Investigation (Task agent): Identified 8 tls_sll_push() call sites and 3 high-risk areas: 1. HIGH: Carve-Push Rollback pop failures (carve_push_box.c) 2. MEDIUM: Splice partial orphaned nodes (tiny_refill_opt.h) 3. MEDIUM: Incomplete double-free scan - only 64 nodes (tls_sll_box.h) Fixes Applied: 1. core/box/carve_push_box.c (Lines 115-139) - Track pop_failed count during rollback - Log orphaned blocks: [BOX_CARVE_PUSH_ROLLBACK] warning - Helps identify when rollback leaves blocks in SLL 2. core/box/tls_sll_box.h (Lines 347-370) - Increase double-free scan: 64 → 256 nodes - Add scanned count to error: (scanned=%u/%u) - Catches orphaned blocks deeper in chain 3. core/tiny_refill_opt.h (Lines 135-166) - Enhanced splice partial logging - Abort in debug builds on orphaned nodes - Prevents silent memory leaks Test Results: Before: SEGV at 220K iterations After: SEGV at 240K iterations (improved detection) [TLS_SLL_PUSH] FATAL double-free: cls=5 ptr=... (scanned=2/71) Impact: ✅ Early detection working (catches at position 2) ✅ Diagnostic capability greatly improved ⚠️ Root cause not yet resolved (deeper investigation needed) Status: Diagnostic improvements committed for further analysis Credit: Root cause analysis by Task agent (Explore) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 08:43:18 +09:00
#if !HAKMEM_BUILD_RELEASE
if (pop_failed > 0) {
fprintf(stderr, "[BOX_CARVE_PUSH_ROLLBACK] WARNING: %u/%u blocks orphaned in SLL (cls=%d)\n",
pop_failed, pushed, class_idx);
}
#endif
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
// Return remaining unpushed blocks to freelist
while (node) {
void* next_unpushed = tiny_next_read(class_idx, node);
tiny_next_write(class_idx, node, meta->freelist);
meta->freelist = node;
node = next_unpushed;
}
// Rollback metadata counters
meta->carved = (uint16_t)((uint32_t)meta->carved - want);
meta->used = (uint16_t)((uint32_t)meta->used - want);
return 0; // All-or-nothing: return 0 on failure
}
pushed++;
node = next;
}
// Step 7: Update active counter (all blocks successfully pushed)
ss_active_add(tls->ss, want);
return want; // Success: all blocks pushed
}
uint32_t box_carve_and_push_with_freelist(int class_idx, uint32_t want) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_carve_and_push_with_freelist");
if (want == 0) return 0;
// Step 1: Check capacity
if (!box_cap_has_room(class_idx, want)) {
return 0;
}
// Step 2: Get TLS slab
TinyTLSSlab* tls = &g_tls_slabs[class_idx];
if (!tls->ss || !tls->meta) {
return 0;
}
TinySlabMeta* meta = tls->meta;
uint32_t sll_cap = box_cap_get(class_idx);
uint32_t pushed = 0;
// Step 3: Try freelist first
while (pushed < want && meta->freelist) {
void* p = meta->freelist;
meta->freelist = tiny_next_read(class_idx, p);
meta->used++;
c7_meta_used_note(class_idx, C7_META_USED_SRC_FRONT);
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
// CRITICAL FIX: Restore header BEFORE pushing to TLS SLL
// Freelist blocks may have stale data at offset 0
Bugfix: Add Header Box and fix Class 0/7 header handling (crash rate -50%) Root Cause Analysis: - tls_sll_box.h had hardcoded `class_idx != 7` checks - This incorrectly assumed only C7 uses offset=0 - But C0 (8B) also uses offset=0 (header overwritten by next pointer) - Result: C0 blocks had corrupted headers in TLS SLL → crash Architecture Fix: Header Box (Single Source of Truth) - Created core/box/tiny_header_box.h - Encapsulates "which classes preserve headers" logic - Delegates to tiny_nextptr.h (0x7E bitmask: C0=0, C1-C6=1, C7=0) - API: * tiny_class_preserves_header() - C1-C6 only * tiny_header_write_if_preserved() - Conditional write * tiny_header_validate() - Conditional validation * tiny_header_write_for_alloc() - Unconditional (alloc path) Bug Fixes (6 locations): - tls_sll_box.h:366 - push header restore (C1-C6 only; skip C0/C7) - tls_sll_box.h:560 - pop header validate (C1-C6 only; skip C0/C7) - tls_sll_box.h:700 - splice header restore head (C1-C6 only) - tls_sll_box.h:722 - splice header restore next (C1-C6 only) - carve_push_box.c:198 - freelist→TLS SLL header restore - hakmem_tiny_free.inc:78 - drain freelist header restore Impact: - Before: 23.8% crash rate (bench_random_mixed_hakmem) - After: 12% crash rate - Improvement: 49.6% reduction in crashes - Test: 88/100 runs successful (vs 76/100 before) Design Principles: - Eliminates hardcoded class_idx checks (class_idx != 7) - Single Source of Truth (tiny_nextptr.h → Header Box) - Type-safe API prevents future bugs - Future: Add lint to forbid direct header manipulation Remaining Work: - 12% crash rate still exists (likely different root cause) - Next: Investigate with core dump analysis 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:57:49 +09:00
// Uses Header Box API (C1-C6 only; C0/C7 skip)
tiny_header_write_if_preserved(p, class_idx);
Box API Phase 1-3: Capacity Manager, Carve-Push, Prewarm 実装 Priority 1-3のBox Modulesを実装し、安全なpre-warming APIを提供。 既存の複雑なprewarmコードを1行のBox API呼び出しに置き換え。 ## 新規Box Modules 1. **Box Capacity Manager** (capacity_box.h/c) - TLS SLL容量の一元管理 - adaptive_sizing初期化保証 - Double-free バグ防止 2. **Box Carve-And-Push** (carve_push_box.h/c) - アトミックなblock carve + TLS SLL push - All-or-nothing semantics - Rollback保証(partial failure防止) 3. **Box Prewarm** (prewarm_box.h/c) - 安全なTLS cache pre-warming - 初期化依存性を隠蔽 - シンプルなAPI (1関数呼び出し) ## コード簡略化 hakmem_tiny_init.inc: 20行 → 1行 ```c // BEFORE: 複雑なP0分岐とエラー処理 adaptive_sizing_init(); if (prewarm > 0) { #if HAKMEM_TINY_P0_BATCH_REFILL int taken = sll_refill_batch_from_ss(5, prewarm); #else int taken = sll_refill_small_from_ss(5, prewarm); #endif } // AFTER: Box API 1行 int taken = box_prewarm_tls(5, prewarm); ``` ## シンボルExport修正 hakmem_tiny.c: 5つのシンボルをstatic → non-static - g_tls_slabs[] (TLS slab配列) - g_sll_multiplier (SLL容量乗数) - g_sll_cap_override[] (容量オーバーライド) - superslab_refill() (SuperSlab再充填) - ss_active_add() (アクティブカウンタ) ## ビルドシステム Makefile: TINY_BENCH_OBJS_BASEに3つのBox modules追加 - core/box/capacity_box.o - core/box/carve_push_box.o - core/box/prewarm_box.o ## 動作確認 ✅ Debug build成功 ✅ Box Prewarm API動作確認 [PREWARM] class=5 requested=128 taken=32 ## 次のステップ - Box Refill Manager (Priority 4) - Box SuperSlab Allocator (Priority 5) - Release build修正(tiny_debug_ring_record) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 01:45:30 +09:00
if (!tls_sll_push(class_idx, p, sll_cap)) {
// Rollback
tiny_next_write(class_idx, p, meta->freelist);
meta->freelist = p;
meta->used--;
// Rollback all pushed
for (uint32_t j = 0; j < pushed; j++) {
void* popped;
if (tls_sll_pop(class_idx, &popped)) {
tiny_next_write(class_idx, popped, meta->freelist);
meta->freelist = popped;
meta->used--;
}
}
return 0;
}
ss_active_add(tls->ss, 1);
pushed++;
}
// Step 4: If still need more, try carving
if (pushed < want) {
uint32_t need = want - pushed;
uint32_t carved = box_carve_and_push(class_idx, need);
if (carved < need) {
// Partial failure: rollback freelist pushes
for (uint32_t j = 0; j < pushed; j++) {
void* popped;
if (tls_sll_pop(class_idx, &popped)) {
tiny_next_write(class_idx, popped, meta->freelist);
meta->freelist = popped;
meta->used--;
ss_active_add(tls->ss, -1);
}
}
return 0;
}
pushed += carved;
}
return pushed;
}