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 最適化時の影響範囲を限定
|
|||
|
|
|