## 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>
779 lines
21 KiB
Markdown
779 lines
21 KiB
Markdown
# hakmem_tiny_free.inc - 構造分析と分割提案
|
||
|
||
## 1. ファイル全体の概要
|
||
|
||
**ファイル統計:**
|
||
| 項目 | 値 |
|
||
|------|-----|
|
||
| **総行数** | 1,711 |
|
||
| **実コード行** | 1,348 (78.7%) |
|
||
| **コメント行** | 257 (15.0%) |
|
||
| **空行** | 107 (6.3%) |
|
||
|
||
**責務エリア別行数:**
|
||
|
||
| 責務エリア | 行数 | コード行 | 割合 |
|
||
|-----------|------|---------|------|
|
||
| Free with TinySlab(両パス) | 558 | 462 | 34.2% |
|
||
| SuperSlab free path | 305 | 281 | 18.7% |
|
||
| SuperSlab allocation & refill | 394 | 308 | 24.1% |
|
||
| Main free entry point | 135 | 116 | 8.3% |
|
||
| Helper functions | 65 | 60 | 4.0% |
|
||
| Shutdown | 30 | 28 | 1.8% |
|
||
|
||
---
|
||
|
||
## 2. 関数一覧と構造
|
||
|
||
**全10関数の詳細マップ:**
|
||
|
||
### Phase 1: Helper Functions (Lines 1-65)
|
||
|
||
```
|
||
1-15 Includes & extern declarations
|
||
16-25 tiny_drain_to_sll_budget() [10 lines] ← ENV-based config
|
||
27-42 tiny_drain_freelist_to_slab_to_sll_once() [16 lines] ← Freelist splicing
|
||
44-64 tiny_remote_queue_contains_guard() [21 lines] ← Remote queue traversal
|
||
```
|
||
|
||
**責務:**
|
||
- TLS SLL へのドレイン予算決定(環境変数ベース)
|
||
- リモートキューの重複検査
|
||
- 重要度: **LOW** (ユーティリティ関数)
|
||
|
||
---
|
||
|
||
### Phase 2: Main Free Path - TinySlab (Lines 68-625)
|
||
|
||
**関数:** `hak_tiny_free_with_slab(void* ptr, TinySlab* slab)` (558行)
|
||
|
||
**構成:**
|
||
```
|
||
68-67 入口・コメント
|
||
70-133 SuperSlab mode (slab == NULL) [64 行]
|
||
- SuperSlab lookup
|
||
- Class validation
|
||
- Safety checks (HAKMEM_SAFE_FREE)
|
||
- Cross-thread detection
|
||
|
||
135-206 Same-thread TLS push paths [72 行]
|
||
- Fast path (g_fast_enable)
|
||
- TLS List push (g_tls_list_enable)
|
||
- HotMag push (g_hotmag_enable)
|
||
|
||
208-620 Magazine/SLL push paths [413 行]
|
||
- TinyQuickSlot handling
|
||
- TLS SLL push (fast)
|
||
- Magazine push (with hysteresis)
|
||
- Background spill (g_bg_spill_enable)
|
||
- Super Registry spill
|
||
- Publisher final fallback
|
||
|
||
622-625 Closing
|
||
```
|
||
|
||
**内部フローチャート:**
|
||
|
||
```
|
||
hak_tiny_free_with_slab(ptr, slab)
|
||
│
|
||
├─ if (!slab) ← SuperSlab path
|
||
│ │
|
||
│ ├─ hak_super_lookup(ptr)
|
||
│ ├─ Class validation
|
||
│ ├─ HAKMEM_SAFE_FREE checks
|
||
│ ├─ Cross-thread detection
|
||
│ │ │
|
||
│ │ └─ if (meta->owner_tid != self_tid)
|
||
│ │ └─ hak_tiny_free_superslab(ptr, ss) ← REMOTE PATH
|
||
│ │ └─ return
|
||
│ │
|
||
│ └─ Same-thread paths (owner_tid == self_tid)
|
||
│ │
|
||
│ ├─ g_fast_enable + tiny_fast_push() ← FAST CACHE
|
||
│ │
|
||
│ ├─ g_tls_list_enable + tls_list push ← TLS LIST
|
||
│ │
|
||
│ └─ Magazine/SLL paths:
|
||
│ ├─ TinyQuickSlot (≤64B)
|
||
│ ├─ TLS SLL push (fast, no lock)
|
||
│ ├─ Magazine push (with hysteresis)
|
||
│ ├─ Background spill (async)
|
||
│ ├─ SuperRegistry spill (with lock)
|
||
│ └─ Publisher fallback
|
||
│
|
||
└─ else ← TinySlab-direct path
|
||
[continues with similar structure]
|
||
```
|
||
|
||
**キー特性:**
|
||
- **責務の多重性**: Free path が複数ポリシーを内包
|
||
- Fast path (タイム測定なし)
|
||
- TLS List (容量制限あり)
|
||
- Magazine (容量チューニング)
|
||
- SLL (ロックフリー)
|
||
- Background async
|
||
- **責任: VERY HIGH** (メイン Free 処理の 34%)
|
||
- **リスク: HIGH** (複数パスの相互作用)
|
||
|
||
---
|
||
|
||
### Phase 3: SuperSlab Allocation Helpers (Lines 626-1019)
|
||
|
||
#### 3a. `superslab_alloc_from_slab()` (Lines 626-709)
|
||
|
||
```
|
||
626-628 入口
|
||
630-663 Remote queue drain(リモートキュー排出)
|
||
665-677 Remote pending check(デバッグ)
|
||
679-708 Linear / Freelist allocation
|
||
- Linear: sequential access (cache-friendly)
|
||
- Freelist: pop from meta->freelist
|
||
```
|
||
|
||
**責務:**
|
||
- SuperSlab の単一スラブからのブロック割り当て
|
||
- リモートキューの管理
|
||
- Linear/Freelist の2パスをサポート
|
||
- **重要度: HIGH** (allocation hot path)
|
||
|
||
---
|
||
|
||
#### 3b. `superslab_refill()` (Lines 712-1019)
|
||
|
||
```
|
||
712-745 初期化・状態キャプチャ
|
||
747-782 Mid-size simple refill(クラス>=4)
|
||
785-947 SuperSlab adoption(published partial の採用)
|
||
- g_ss_adopt_en フラグチェック
|
||
- クールダウン管理
|
||
- First-fit slab スキャン
|
||
- Best-fit scoring
|
||
- slab acquisition & binding
|
||
|
||
949-1019 SuperSlab allocation(新規作成)
|
||
- superslab_allocate()
|
||
- slab init & binding
|
||
- refcount管理
|
||
```
|
||
|
||
**キー特性:**
|
||
- **複雑度: VERY HIGH**
|
||
- Adoption vs allocation decision logic
|
||
- Scoring algorithm (lines 850-947)
|
||
- Multi-layer registry scan
|
||
- **責任: HIGH** (24% of file)
|
||
- **最適化ターゲット**: Phase P0 最適化(`nonempty_mask` で O(n) → O(1) 化)
|
||
|
||
**内部フロー:**
|
||
```
|
||
superslab_refill(class_idx)
|
||
│
|
||
├─ Try mid_simple_refill (if class >= 4)
|
||
│ ├─ Use existing TLS SuperSlab's virgin slab
|
||
│ └─ return
|
||
│
|
||
├─ Try ss_partial_adopt() (if g_ss_adopt_en)
|
||
│ ├─ First-fit or Best-fit scoring
|
||
│ ├─ slab_try_acquire()
|
||
│ ├─ tiny_tls_bind_slab()
|
||
│ └─ return adopted
|
||
│
|
||
└─ superslab_allocate() (fresh allocation)
|
||
├─ Allocate new SuperSlab memory
|
||
├─ superslab_init_slab(slab_0)
|
||
├─ tiny_tls_bind_slab()
|
||
└─ return new
|
||
```
|
||
|
||
---
|
||
|
||
### Phase 4: SuperSlab Allocation Entry (Lines 1020-1170)
|
||
|
||
**関数:** `hak_tiny_alloc_superslab()` (151行)
|
||
|
||
```
|
||
1020-1024 入口・ENV検査
|
||
1026-1169 TLS lookup + refill logic
|
||
- TLS cache hit (fast)
|
||
- Linear/Freelist allocation
|
||
- Refill on miss
|
||
- Adopt/allocate decision
|
||
```
|
||
|
||
**責務:**
|
||
- SuperSlab-based allocation の main entry point
|
||
- TLS キャッシュ管理
|
||
- **重要度: MEDIUM** (allocation のみ, free ではない)
|
||
|
||
---
|
||
|
||
### Phase 5: SuperSlab Free Path (Lines 1171-1475)
|
||
|
||
**関数:** `hak_tiny_free_superslab()` (305行)
|
||
|
||
```
|
||
1171-1198 入口・デバッグ
|
||
1200-1230 Validation & safety checks
|
||
- size_class bounds checking
|
||
- slab_idx validation
|
||
- Double-free detection
|
||
|
||
1232-1310 Same-thread free path [79 lines]
|
||
- ROUTE_MARK tracking
|
||
- Direct freelist push
|
||
- remote guard check
|
||
- MidTC (TLS tcache) integration
|
||
- First-free publish detection
|
||
|
||
1312-1470 Remote/cross-thread path [159 lines]
|
||
- Remote queue enqueue
|
||
- Pending drain check
|
||
- Remote sentinel validation
|
||
- Bulk refill coordination
|
||
```
|
||
|
||
**キー特性:**
|
||
- **責務: HIGH** (18.7% of file)
|
||
- **複雑度: VERY HIGH**
|
||
- Same-thread vs remote path の分岐
|
||
- Remote queue management
|
||
- Sentinel validation
|
||
- Guard transitions (ROUTE_MARK)
|
||
|
||
**内部フロー:**
|
||
```
|
||
hak_tiny_free_superslab(ptr, ss)
|
||
│
|
||
├─ Validation (bounds, magic, size_class)
|
||
│
|
||
├─ if (same-thread: owner_tid == my_tid)
|
||
│ ├─ tiny_free_local_box() → freelist push
|
||
│ ├─ first-free → publish detection
|
||
│ └─ MidTC integration
|
||
│
|
||
└─ else (remote/cross-thread)
|
||
├─ tiny_free_remote_box() → remote queue
|
||
├─ Sentinel validation
|
||
└─ Bulk refill coordination
|
||
```
|
||
|
||
---
|
||
|
||
### Phase 6: Main Free Entry Point (Lines 1476-1610)
|
||
|
||
**関数:** `hak_tiny_free()` (135行)
|
||
|
||
```
|
||
1476-1478 入口チェック
|
||
1482-1505 HAKMEM_TINY_BENCH_SLL_ONLY mode(ベンチ用)
|
||
1507-1529 TINY_ULTRA mode(ultra-simple path)
|
||
1531-1575 Fast class resolution + Fast path attempt
|
||
- SuperSlab lookup (g_use_superslab)
|
||
- TinySlab lookup (fallback)
|
||
- Fast cache push attempt
|
||
|
||
1577-1596 SuperSlab dispatch
|
||
1598-1610 TinySlab fallback
|
||
```
|
||
|
||
**責務:**
|
||
- Global free() エントリポイント
|
||
- Mode selection (benchmark/ultra/normal)
|
||
- Class resolution
|
||
- hak_tiny_free_with_slab() への delegation
|
||
- **重要度: MEDIUM** (8.3%)
|
||
- **責任: Dispatch + routing only**
|
||
|
||
---
|
||
|
||
### Phase 7: Shutdown (Lines 1676-1705)
|
||
|
||
**関数:** `hak_tiny_shutdown()` (30行)
|
||
|
||
```
|
||
1676-1686 TLS SuperSlab refcount cleanup
|
||
1687-1694 Background bin thread shutdown
|
||
1695-1704 Intelligence Engine shutdown
|
||
```
|
||
|
||
**責務:**
|
||
- Resource cleanup
|
||
- Thread termination
|
||
- **重要度: LOW** (1.8%)
|
||
|
||
---
|
||
|
||
## 3. 責任範囲の詳細分析
|
||
|
||
### 3.1 By Responsibility Domain
|
||
|
||
**Free Paths:**
|
||
- Same-thread (TinySlab): lines 135-206, 1232-1310
|
||
- Same-thread (SuperSlab via hak_tiny_free_with_slab): lines 70-133
|
||
- Remote/cross-thread (SuperSlab): lines 1312-1470
|
||
- Magazine/SLL (async): lines 208-620
|
||
|
||
**Allocation Paths:**
|
||
- SuperSlab alloc: lines 626-709
|
||
- SuperSlab refill: lines 712-1019
|
||
- SuperSlab entry: lines 1020-1170
|
||
|
||
**Management:**
|
||
- Remote queue guard: lines 44-64
|
||
- SLL drain: lines 27-42
|
||
- Shutdown: lines 1676-1705
|
||
|
||
### 3.2 External Dependencies
|
||
|
||
**本ファイル内で定義:**
|
||
- `hak_tiny_free()` [PUBLIC]
|
||
- `hak_tiny_free_with_slab()` [PUBLIC]
|
||
- `hak_tiny_shutdown()` [PUBLIC]
|
||
- All other functions [STATIC]
|
||
|
||
**依存先ファイル:**
|
||
```
|
||
tiny_remote.h
|
||
├─ tiny_remote_track_*
|
||
├─ tiny_remote_queue_contains_guard
|
||
├─ tiny_remote_pack_diag
|
||
└─ tiny_remote_side_get
|
||
|
||
slab_handle.h
|
||
├─ slab_try_acquire()
|
||
├─ slab_drain_remote_full()
|
||
├─ slab_release()
|
||
└─ slab_is_valid()
|
||
|
||
tiny_refill.h
|
||
├─ tiny_tls_bind_slab()
|
||
├─ superslab_find_free_slab()
|
||
├─ superslab_init_slab()
|
||
├─ ss_partial_adopt()
|
||
├─ ss_partial_publish()
|
||
└─ ss_active_dec_one()
|
||
|
||
tiny_tls_guard.h
|
||
├─ tiny_tls_list_guard_push()
|
||
├─ tiny_tls_refresh_params()
|
||
└─ tls_list_* functions
|
||
|
||
mid_tcache.h
|
||
├─ midtc_enabled()
|
||
└─ midtc_push()
|
||
|
||
hakmem_tiny_magazine.h (BUILD_RELEASE=0)
|
||
├─ TinyTLSMag structure
|
||
├─ mag operations
|
||
└─ hotmag_push()
|
||
|
||
box/free_publish_box.h
|
||
box/free_remote_box.h (line 1252)
|
||
box/free_local_box.h (line 1287)
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 関数間の呼び出し関係
|
||
|
||
```
|
||
[Global Entry Points]
|
||
hak_tiny_free()
|
||
└─ (1531-1609) Dispatch logic
|
||
│
|
||
├─> hak_tiny_free_with_slab(ptr, NULL) [SS mode]
|
||
│ └─> hak_tiny_free_superslab() [Remote path]
|
||
│
|
||
├─> hak_tiny_free_with_slab(ptr, slab) [TS mode]
|
||
│
|
||
└─> hak_tiny_free_superslab() [Direct dispatch]
|
||
|
||
hak_tiny_free_with_slab(ptr, slab) [Lines 68-625]
|
||
├─> Magazine/SLL management
|
||
│ ├─ tiny_fast_push()
|
||
│ ├─ tls_list_push()
|
||
│ ├─ hotmag_push()
|
||
│ ├─ bulk_mag_to_sll_if_room()
|
||
│ ├─ [background spill]
|
||
│ └─ [super registry spill]
|
||
│
|
||
└─> hak_tiny_free_superslab() [Remote transition]
|
||
[Lines 1171-1475]
|
||
|
||
hak_tiny_free_superslab()
|
||
├─> (same-thread) tiny_free_local_box()
|
||
│ └─ Direct freelist push
|
||
├─> (remote) tiny_free_remote_box()
|
||
│ └─ Remote queue enqueue
|
||
└─> tiny_remote_queue_contains_guard() [Duplicate check]
|
||
|
||
[Allocation]
|
||
hak_tiny_alloc_superslab()
|
||
└─> superslab_refill()
|
||
├─> ss_partial_adopt()
|
||
│ ├─ slab_try_acquire()
|
||
│ ├─ slab_drain_remote_full()
|
||
│ └─ slab_release()
|
||
│
|
||
└─> superslab_allocate()
|
||
└─> superslab_init_slab()
|
||
|
||
superslab_alloc_from_slab() [Helper for refill]
|
||
├─> slab_try_acquire()
|
||
└─> slab_drain_remote_full()
|
||
|
||
[Utilities]
|
||
tiny_drain_to_sll_budget() [Config getter]
|
||
tiny_remote_queue_contains_guard() [Duplicate validation]
|
||
|
||
[Shutdown]
|
||
hak_tiny_shutdown()
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 分割候補の特定
|
||
|
||
### **分割の根拠:**
|
||
|
||
1. **関数数**: 10個 → サイズ大きい
|
||
2. **責務の混在**: Free, Allocation, Magazine, Remote queue all mixed
|
||
3. **再利用性**: Allocation 関数は独立可能
|
||
4. **テスト容易性**: Remote queue と同期ロジックは隔離可能
|
||
5. **メンテナンス性**: 558行 の `hak_tiny_free_with_slab()` は理解困難
|
||
|
||
### **分割可能性スコア:**
|
||
|
||
| セクション | 独立度 | 複雑度 | サイズ | 優先度 |
|
||
|-----------|--------|--------|--------|--------|
|
||
| Helper (drain, remote guard) | ★★★★★ | ★☆☆☆☆ | 65行 | **P3** (LOW) |
|
||
| Magazine/SLL management | ★★★★☆ | ★★★★☆ | 413行 | **P1** (HIGH) |
|
||
| Same-thread free paths | ★★★☆☆ | ★★★☆☆ | 72行 | **P2** (MEDIUM) |
|
||
| SuperSlab alloc/refill | ★★★★☆ | ★★★★★ | 394行 | **P1** (HIGH) |
|
||
| SuperSlab free path | ★★★☆☆ | ★★★★★ | 305行 | **P1** (HIGH) |
|
||
| Main entry point | ★★★★★ | ★★☆☆☆ | 135行 | **P2** (MEDIUM) |
|
||
| Shutdown | ★★★★★ | ★☆☆☆☆ | 30行 | **P3** (LOW) |
|
||
|
||
---
|
||
|
||
## 6. 推奨される分割案(3段階)
|
||
|
||
### **Phase 1: Magazine/SLL 関連を分離**
|
||
|
||
**新ファイル: `tiny_free_magazine.inc.h`** (413行 → 400行推定)
|
||
|
||
**含める関数:**
|
||
- Magazine push/spill logic
|
||
- TLS SLL push
|
||
- HotMag handling
|
||
- Background spill
|
||
- Super Registry spill
|
||
- Publisher fallback
|
||
|
||
**呼び出し元から参照:**
|
||
```c
|
||
// In hak_tiny_free_with_slab()
|
||
#include "tiny_free_magazine.inc.h"
|
||
if (tls_list_enabled) {
|
||
tls_list_push(class_idx, ptr);
|
||
// ...
|
||
}
|
||
// Then continue with magazine code via include
|
||
```
|
||
|
||
**メリット:**
|
||
- Magazine は独立した "レイヤー" (Policy pattern)
|
||
- 環境変数で on/off 可能
|
||
- テスト時に完全に mock 可能
|
||
- 関数削減: 8個 → 6個
|
||
|
||
---
|
||
|
||
### **Phase 2: SuperSlab Allocation を分離**
|
||
|
||
**新ファイル: `tiny_superslab_alloc.inc.h`** (394行 → 380行推定)
|
||
|
||
**含める関数:**
|
||
```c
|
||
static SuperSlab* superslab_refill(int class_idx)
|
||
static inline void* superslab_alloc_from_slab(SuperSlab* ss, int slab_idx)
|
||
static inline void* hak_tiny_alloc_superslab(int class_idx)
|
||
// + adoption & registry helpers
|
||
```
|
||
|
||
**呼び出し元:**
|
||
- `hak_tiny_free.inc` (main entry point のみ)
|
||
- 他のファイル (already external)
|
||
|
||
**メリット:**
|
||
- Allocation は free と直交
|
||
- Adoption logic は独立テスト可能
|
||
- Registry optimization (P0) は此処に focused
|
||
- Hot path を明確化
|
||
|
||
---
|
||
|
||
### **Phase 3: SuperSlab Free を分離**
|
||
|
||
**新ファイル: `tiny_superslab_free.inc.h`** (305行 → 290行推定)
|
||
|
||
**含める関数:**
|
||
```c
|
||
static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss)
|
||
// + remote/local box includes (inline)
|
||
```
|
||
|
||
**責務:**
|
||
- Same-thread freelist push
|
||
- Remote queue management
|
||
- Sentinel validation
|
||
- First-free publish detection
|
||
|
||
**メリット:**
|
||
- Remote queue logic は純粋 (no allocation)
|
||
- Cross-thread free は critical path
|
||
- Debugging が簡単 (ROUTE_MARK)
|
||
|
||
---
|
||
|
||
## 7. 分割後のファイル構成
|
||
|
||
### **Current:**
|
||
```
|
||
hakmem_tiny_free.inc (1,711行)
|
||
├─ Includes (8行)
|
||
├─ Helpers (65行)
|
||
├─ hak_tiny_free_with_slab (558行)
|
||
│ ├─ Magazine/SLL paths (413行)
|
||
│ └─ TinySlab path (145行)
|
||
├─ SuperSlab alloc/refill (394行)
|
||
├─ SuperSlab free (305行)
|
||
├─ hak_tiny_free (135行)
|
||
├─ [extracted queries] (50行)
|
||
└─ hak_tiny_shutdown (30行)
|
||
```
|
||
|
||
### **After Phase 1-3 Refactoring:**
|
||
|
||
```
|
||
hakmem_tiny_free.inc (450行)
|
||
├─ Includes (8行)
|
||
├─ Helpers (65行)
|
||
├─ hak_tiny_free_with_slab (stub, delegates)
|
||
├─ hak_tiny_free (main entry) (135行)
|
||
├─ hak_tiny_shutdown (30行)
|
||
└─ #include "tiny_superslab_alloc.inc.h"
|
||
└─ #include "tiny_superslab_free.inc.h"
|
||
└─ #include "tiny_free_magazine.inc.h"
|
||
|
||
tiny_superslab_alloc.inc.h (380行)
|
||
├─ superslab_refill()
|
||
├─ superslab_alloc_from_slab()
|
||
├─ hak_tiny_alloc_superslab()
|
||
├─ Adoption/registry logic
|
||
|
||
tiny_superslab_free.inc.h (290行)
|
||
├─ hak_tiny_free_superslab()
|
||
├─ Remote queue management
|
||
├─ Sentinel validation
|
||
|
||
tiny_free_magazine.inc.h (400行)
|
||
├─ Magazine push/spill
|
||
├─ TLS SLL management
|
||
├─ HotMag integration
|
||
├─ Background spill
|
||
```
|
||
|
||
---
|
||
|
||
## 8. インターフェース設計
|
||
|
||
### **Internal Dependencies (headers needed):**
|
||
|
||
**`tiny_superslab_alloc.inc.h` は以下を require:**
|
||
```c
|
||
#include "tiny_refill.h" // ss_partial_adopt, superslab_allocate
|
||
#include "slab_handle.h" // slab_try_acquire
|
||
#include "tiny_remote.h" // remote tracking
|
||
```
|
||
|
||
**`tiny_superslab_free.inc.h` は以下を require:**
|
||
```c
|
||
#include "box/free_local_box.h"
|
||
#include "box/free_remote_box.h"
|
||
#include "tiny_remote.h" // validation
|
||
#include "slab_handle.h" // slab_index_for
|
||
```
|
||
|
||
**`tiny_free_magazine.inc.h` は以下を require:**
|
||
```c
|
||
#include "hakmem_tiny_magazine.h" // Magazine structures
|
||
#include "tiny_tls_guard.h" // TLS list ops
|
||
#include "mid_tcache.h" // MidTC
|
||
// + many helper functions already in scope
|
||
```
|
||
|
||
### **New Integration Header:**
|
||
|
||
**`tiny_free_internal.h`** (新規作成)
|
||
```c
|
||
// Public exports from tiny_free.inc components
|
||
extern void hak_tiny_free(void* ptr);
|
||
extern void hak_tiny_free_with_slab(void* ptr, TinySlab* slab);
|
||
extern void hak_tiny_shutdown(void);
|
||
|
||
// Internal allocation API (for free path)
|
||
extern void* hak_tiny_alloc_superslab(int class_idx);
|
||
extern static void hak_tiny_free_superslab(void* ptr, SuperSlab* ss);
|
||
|
||
// Forward declarations for cross-component calls
|
||
struct TinySlabMeta;
|
||
struct SuperSlab;
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 分割後の呼び出しフロー(改善版)
|
||
|
||
```
|
||
[hak_tiny_free.inc]
|
||
hak_tiny_free(ptr)
|
||
├─ mode selection (BENCH, ULTRA, NORMAL)
|
||
├─ class resolution
|
||
│ └─ SuperSlab lookup OR TinySlab lookup
|
||
│
|
||
└─> (if SuperSlab)
|
||
├─ DISPATCH: #include "tiny_superslab_free.inc.h"
|
||
│ └─ hak_tiny_free_superslab(ptr, ss)
|
||
│ ├─ same-thread: freelist push
|
||
│ └─ remote: queue enqueue
|
||
│
|
||
└─ (if TinySlab)
|
||
├─ DISPATCH: #include "tiny_superslab_alloc.inc.h" [if needed for refill]
|
||
└─ DISPATCH: #include "tiny_free_magazine.inc.h"
|
||
├─ Fast cache?
|
||
├─ TLS list?
|
||
├─ Magazine?
|
||
├─ SLL?
|
||
├─ Background spill?
|
||
└─ Publisher fallback?
|
||
|
||
[tiny_superslab_alloc.inc.h]
|
||
hak_tiny_alloc_superslab(class_idx)
|
||
└─ superslab_refill()
|
||
├─ adoption: ss_partial_adopt()
|
||
└─ allocate: superslab_allocate()
|
||
|
||
[tiny_superslab_free.inc.h]
|
||
hak_tiny_free_superslab(ptr, ss)
|
||
├─ (same-thread) tiny_free_local_box()
|
||
└─ (remote) tiny_free_remote_box()
|
||
|
||
[tiny_free_magazine.inc.h]
|
||
magazine_push_or_spill(class_idx, ptr)
|
||
├─ quick slot?
|
||
├─ SLL?
|
||
├─ magazine?
|
||
├─ background spill?
|
||
└─ publisher?
|
||
```
|
||
|
||
---
|
||
|
||
## 10. メリット・デメリット分析
|
||
|
||
### **分割のメリット:**
|
||
|
||
| メリット | 詳細 |
|
||
|---------|------|
|
||
| **理解容易性** | 各ファイルが単一責務(Free / Alloc / Magazine)|
|
||
| **テスト容易性** | Magazine 層を mock して free path テスト可能 |
|
||
| **リビジョン追跡** | Magazine スパイル改善時に superslab_free は影響なし |
|
||
| **並列開発** | 3つのファイルを独立で開発・最適化可能 |
|
||
| **再利用** | `tiny_superslab_alloc.inc.h` を alloc.inc でも再利用可能 |
|
||
| **デバッグ** | 各層の enable/disable フラグで検証容易 |
|
||
|
||
### **分割のデメリット:**
|
||
|
||
| デメリット | 対策 |
|
||
|-----------|------|
|
||
| **include 増加** | 3個 include (acceptable, `#include` guard) |
|
||
| **複雑度追加** | モジュール図を CLAUDE.md に記載 |
|
||
| **circular dependency risk** | `tiny_free_internal.h` で forwarding declaration |
|
||
| **マージ困難** | git rebase 時に conflict (minor) |
|
||
|
||
---
|
||
|
||
## 11. 実装ロードマップ
|
||
|
||
### **Step 1: バックアップ**
|
||
```bash
|
||
cp core/hakmem_tiny_free.inc core/hakmem_tiny_free.inc.bak
|
||
```
|
||
|
||
### **Step 2: `tiny_free_magazine.inc.h` 抽出**
|
||
- Lines 208-620 を新ファイルに
|
||
- External function prototype をヘッダに
|
||
- hakmem_tiny_free.inc で `#include` に置換
|
||
|
||
### **Step 3: `tiny_superslab_alloc.inc.h` 抽出**
|
||
- Lines 626-1019 を新ファイルに
|
||
- hakmem_tiny_free.inc で `#include` に置換
|
||
|
||
### **Step 4: `tiny_superslab_free.inc.h` 抽出**
|
||
- Lines 1171-1475 を新ファイルに
|
||
- hakmem_tiny_free.inc で `#include` に置換
|
||
|
||
### **Step 5: テスト & ビルド確認**
|
||
```bash
|
||
make clean && make
|
||
./larson_hakmem ... # Regression テスト
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 現在の複雑度指標
|
||
|
||
**サイクロマティック複雑度 (推定):**
|
||
|
||
| 関数 | CC | リスク |
|
||
|------|----|----|
|
||
| hak_tiny_free_with_slab | 28 | ★★★★★ CRITICAL |
|
||
| superslab_refill | 18 | ★★★★☆ HIGH |
|
||
| hak_tiny_free_superslab | 16 | ★★★★☆ HIGH |
|
||
| hak_tiny_free | 12 | ★★★☆☆ MEDIUM |
|
||
| superslab_alloc_from_slab | 4 | ★☆☆☆☆ LOW |
|
||
|
||
**分割により:**
|
||
- hak_tiny_free_with_slab: 28 → 8-12 (中規模に削減)
|
||
- 複数の小さい関数に分散
|
||
- 各ファイルが「焦点を絞った責務」に
|
||
|
||
---
|
||
|
||
## 13. 関連ドキュメント参照
|
||
|
||
- **CLAUDE.md**: Phase 6-2.1 P0 最適化 (superslab_refill の O(n)→O(1) 化)
|
||
- **HISTORY.md**: 過去の分割失敗 (Phase 5-B-Simple)
|
||
- **LARSON_GUIDE.md**: ビルド・テスト方法
|
||
|
||
---
|
||
|
||
## サマリー
|
||
|
||
| 項目 | 現状 | 分割後 |
|
||
|------|------|--------|
|
||
| **ファイル数** | 1 | 4 |
|
||
| **総行数** | 1,711 | 1,520 (include overhead相殺) |
|
||
| **平均関数サイズ** | 171行 | 95行 |
|
||
| **最大関数サイズ** | 558行 | 305行 |
|
||
| **理解難易度** | ★★★★☆ | ★★★☆☆ |
|
||
| **テスト容易性** | ★★☆☆☆ | ★★★★☆ |
|
||
|
||
**推奨実施:** **YES** - Magazine/SLL + SuperSlab free を分離することで
|
||
- 主要な複雑性 (CC 28) を 4-8 に削減
|
||
- Free path と allocation path を明確に分離
|
||
- Magazine 最適化時の影響範囲を限定
|
||
|