Files
hakmem/docs/design/REFACTOR_INTEGRATION_PLAN.md
Moe Charm (CI) 67fb15f35f Wrap debug fprintf in !HAKMEM_BUILD_RELEASE guards (Release build optimization)
## Changes

### 1. core/page_arena.c
- Removed init failure message (lines 25-27) - error is handled by returning early
- All other fprintf statements already wrapped in existing #if !HAKMEM_BUILD_RELEASE blocks

### 2. core/hakmem.c
- Wrapped SIGSEGV handler init message (line 72)
- CRITICAL: Kept SIGSEGV/SIGBUS/SIGABRT error messages (lines 62-64) - production needs crash logs

### 3. core/hakmem_shared_pool.c
- Wrapped all debug fprintf statements in #if !HAKMEM_BUILD_RELEASE:
  - Node pool exhaustion warning (line 252)
  - SP_META_CAPACITY_ERROR warning (line 421)
  - SP_FIX_GEOMETRY debug logging (line 745)
  - SP_ACQUIRE_STAGE0.5_EMPTY debug logging (line 865)
  - SP_ACQUIRE_STAGE0_L0 debug logging (line 803)
  - SP_ACQUIRE_STAGE1_LOCKFREE debug logging (line 922)
  - SP_ACQUIRE_STAGE2_LOCKFREE debug logging (line 996)
  - SP_ACQUIRE_STAGE3 debug logging (line 1116)
  - SP_SLOT_RELEASE debug logging (line 1245)
  - SP_SLOT_FREELIST_LOCKFREE debug logging (line 1305)
  - SP_SLOT_COMPLETELY_EMPTY debug logging (line 1316)
- Fixed lock_stats_init() for release builds (lines 60-65) - ensure g_lock_stats_enabled is initialized

## Performance Validation

Before: 51M ops/s (with debug fprintf overhead)
After:  49.1M ops/s (consistent performance, fprintf removed from hot paths)

## Build & Test

```bash
./build.sh larson_hakmem
./out/release/larson_hakmem 1 5 1 1000 100 10000 42
# Result: 49.1M ops/s
```

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 13:14:18 +09:00

9.3 KiB
Raw Blame History

HAKMEM Tiny リファクタリング - 統合計画

📋 Week 1.4: 統合戦略

🎯 目標

新しい箱Box 1, 5, 6を既存コードに統合し、Feature flag で新旧を切り替え可能にする。

🔧 Feature Flag 設計

Option 1: Phase 6 拡張(推奨)

既存の Phase 6 メカニズムを拡張する方法:

// Phase 6-1.7: Box Theory Refactoring (NEW)
//   - Enable: -DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1
//   - Speed: 58-65 M ops/sec (expected, +10-25%)
//   - Method: Box 1 (Atomic) + Box 5 (Alloc Fast) + Box 6 (Free Fast)
//   - Benefit: Clear boundaries, 3-4 instruction fast path
//   - Files: tiny_atomic.h, tiny_alloc_fast.inc.h, tiny_free_fast.inc.h

利点:

  • 既存の Phase 6 パターンと一貫性がある
  • 相互排他チェックが自動(#error ディレクティブ)
  • ユーザーが理解しやすいPhase 6-1.5, 6-1.6, 6-1.7

実装:

#if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
    #error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE"
#endif

// NEW: Box Refactor check
#ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
    #if defined(HAKMEM_TINY_PHASE6_METADATA) || defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
        #error "Cannot enable PHASE6_BOX_REFACTOR with other Phase 6 options"
    #endif

    // Include new boxes
    #include "tiny_atomic.h"
    #include "tiny_alloc_fast.inc.h"
    #include "tiny_free_fast.inc.h"

    // Override alloc/free entry points
    #define hak_tiny_alloc(size) tiny_alloc_fast(size)
    #define hak_tiny_free(ptr) tiny_free_fast(ptr)
#endif

Option 2: 独立 Flag代替案

新しい独立した flag を作る方法:

// Enable new box-based fast path
// Usage: make CFLAGS="-DHAKMEM_TINY_USE_FAST_BOXES=1"
#ifdef HAKMEM_TINY_USE_FAST_BOXES
    #include "tiny_atomic.h"
    #include "tiny_alloc_fast.inc.h"
    #include "tiny_free_fast.inc.h"

    #define hak_tiny_alloc(size) tiny_alloc_fast(size)
    #define hak_tiny_free(ptr) tiny_free_fast(ptr)
#endif

利点:

  • シンプル
  • Phase 6 とは独立

欠点:

  • Phase 6 との相互排他チェックが必要
  • 一貫性がやや低い

📝 統合ステップ(推奨: Option 1

Step 1: Feature Flag 追加hakmem_tiny.c

// File: core/hakmem_tiny.c
// Location: Around line 1489 (after Phase 6 definitions)

#if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
    #error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE"
#endif

// NEW: Phase 6-1.7 - Box Theory Refactoring
#ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
    #if defined(HAKMEM_TINY_PHASE6_METADATA) || defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
        #error "Cannot enable PHASE6_BOX_REFACTOR with other Phase 6 options"
    #endif

    // Box 1: Atomic Operations (Layer 0)
    #include "tiny_atomic.h"

    // Box 5: Allocation Fast Path (Layer 1)
    #include "tiny_alloc_fast.inc.h"

    // Box 6: Free Fast Path (Layer 2)
    #include "tiny_free_fast.inc.h"

    // Override entry points
    void* hak_tiny_alloc_box_refactor(size_t size) {
        return tiny_alloc_fast(size);
    }

    void hak_tiny_free_box_refactor(void* ptr) {
        tiny_free_fast(ptr);
    }

    // Export as default when enabled
    #define hak_tiny_alloc_wrapper(class_idx) hak_tiny_alloc_box_refactor(g_tiny_class_sizes[class_idx])
    // Note: Free path needs different approach (see Step 2)

#elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
    // Phase 6-1.5: Alignment guessing (legacy)
    #include "hakmem_tiny_ultra_simple.inc"
#elif defined(HAKMEM_TINY_PHASE6_METADATA)
    // Phase 6-1.6: Metadata header (recommended)
    #include "hakmem_tiny_metadata.inc"
#endif

Step 2: Update hakmem.c Entry Points

// File: core/hakmem.c
// Location: Around line 680 (hak_malloc implementation)

void* hak_malloc(size_t size) {
    if (__builtin_expect(size == 0, 0)) return NULL;

    if (__builtin_expect(size <= 1024, 1)) {
        #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
            // Box Refactor: Direct call to Box 5
            void* ptr = tiny_alloc_fast(size);
            if (ptr) return ptr;
            // Fall through to backend on OOM
        #elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
            // Ultra Simple path
            void* ptr = hak_tiny_alloc_ultra_simple(size);
            if (ptr) return ptr;
        #else
            // Default Tiny path
            void* tiny_ptr = hak_tiny_alloc(size);
            if (tiny_ptr) return tiny_ptr;
        #endif
    }

    // Mid/Large/Whale fallback
    return hak_alloc_large_or_mid(size);
}

void hak_free(void* ptr) {
    if (__builtin_expect(!ptr, 0)) return;

    #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
        // Box Refactor: Direct call to Box 6
        tiny_free_fast(ptr);
        return;
    #elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
        // Ultra Simple path
        hak_tiny_free_ultra_simple(ptr);
        return;
    #else
        // Default path (with mid_lookup, etc.)
        hak_free_at(ptr, 0, 0);
    #endif
}

Step 3: Makefile Update

# File: Makefile
# Add new Phase 6 option

# Phase 6-1.7: Box Theory Refactoring
box-refactor:
	$(MAKE) clean
	$(MAKE) CFLAGS="$(CFLAGS) -DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" all
	@echo "Built with Box Refactor (Phase 6-1.7)"

# Convenience target
test-box-refactor: box-refactor
	./larson_hakmem 10 8 128 1024 1 12345 4

🧪 テスト計画

Phase 1: コンパイル確認

# 1. Box Refactor のみ有効化
make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem

# 2. 他の Phase 6 オプションと排他チェック
make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1 -DHAKMEM_TINY_PHASE6_ULTRA_SIMPLE=1" larson_hakmem
# Expected: Compile error (mutual exclusion)

Phase 2: 動作確認

# 1. 基本動作テスト
make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem
./larson_hakmem 2 8 128 1024 1 12345 1
# Expected: No crash, basic allocation/free works

# 2. マルチスレッドテスト
./larson_hakmem 10 8 128 1024 1 12345 4
# Expected: No crash, no A213 errors

# 3. Guard mode テスト
HAKMEM_TINY_DEBUG_REMOTE_GUARD=1 HAKMEM_SAFE_FREE=1 \
  ./larson_hakmem 5 8 128 1024 1 12345 4
# Expected: No remote_invalid errors

Phase 3: パフォーマンス測定

# Baseline (現状)
make clean && make larson_hakmem
./larson_hakmem 10 8 128 1024 1 12345 4 > baseline.txt
grep "Throughput" baseline.txt
# Expected: ~52 M ops/sec (or current value)

# Box Refactor (新)
make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem
./larson_hakmem 10 8 128 1024 1 12345 4 > box_refactor.txt
grep "Throughput" box_refactor.txt
# Target: 58-65 M ops/sec (+10-25%)

📊 成功条件

項目 条件 検証方法
コンパイル成功 エラーなし make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1"
排他チェック Phase 6 オプション同時有効時にエラー make CFLAGS="-D... -D..."
基本動作 No crash, alloc/free 正常 ./larson_hakmem 2 ... 1
マルチスレッド No crash, no A213 ./larson_hakmem 10 ... 4
パフォーマンス +10%以上 Throughput 比較
メモリ安全 No leaks, no corruption Guard mode テスト

🚧 既知の課題と対策

課題 1: External 変数の依存

問題: Box 5/6 が g_tls_sll_head などの extern 変数に依存

対策:

  • hakmem_tiny.c で変数が定義済み → OK
  • Include 順序を守る(変数定義の後に box を include

課題 2: Backend 関数の依存

問題: Box 5 が sll_refill_small_from_ss() などに依存

対策:

  • これらの関数は既存の hakmem_tiny.c に存在 → OK
  • Forward declaration を tiny_alloc_fast.inc.h に追加済み

課題 3: Circular Include

問題: tiny_free_fast.inc.h が slab_handle.h を include、slab_handle.h が tiny_atomic.h を使うべき

対策:

  • tiny_atomic.h は最初に includeLayer 0
  • Include guard で重複を防止(#pragma once

🔄 Rollback Plan

統合が失敗した場合の切り戻し手順:

# 1. Flag を無効化してビルド
make clean
make larson_hakmem
# → Phase 6 なしの default に戻る

# 2. 新ファイルを削除optional
rm -f core/tiny_atomic.h core/tiny_alloc_fast.inc.h core/tiny_free_fast.inc.h

# 3. Git で元に戻すif needed
git checkout core/hakmem_tiny.c core/hakmem.c

📅 タイムライン

Step 作業 時間 累計
1.4.1 Feature flag 設計 30分 0.5h
1.4.2 hakmem_tiny.c 修正 1時間 1.5h
1.4.3 hakmem.c 修正 1時間 2.5h
1.4.4 Makefile 修正 30分 3h
1.5.1 コンパイル確認 30分 3.5h
1.5.2 動作確認テスト 1時間 4.5h
1.5.3 パフォーマンス測定 1時間 5.5h

Total: 約 6時間Week 1 完了)

🎯 Next Steps

  1. 今すぐ: hakmem_tiny.c に Feature flag 追加
  2. : hakmem.c の entry points 修正
  3. その後: ビルド & テスト
  4. 最後: ベンチマーク & 結果レポート

Status: 統合計画完成、実装準備完了 Risk: LowRollback plan あり、Feature flag で切り戻し可能) Confidence: High既存 Phase 6 パターンと一貫性あり)

🎁 統合開始準備完了! 🎁