# CURRENT TASK (Phase 12: Shared SuperSlab Pool – Debug Phase) Phase12 の設計に沿った shared SuperSlab pool 実装および Box API 境界リファクタリングは導入済み。 現在は **shared backend 有効状態での SEGV 解消と安定化** を行うデバッグフェーズに入っている。 本タスクでは以下をゴールとする: - shared Superslab pool backend (`hakmem_shared_pool.[ch]` + `hak_tiny_alloc_superslab_backend_shared`) を Box API (`hak_tiny_alloc_superslab_box`) 経由で安全に運用できる状態にする。 - `bench_random_mixed_hakmem` 実行時に SEGV が発生しないことを確認し、 shared backend を実用レベルの「最小安定実装」として確定させる。 --- ## 2. 現状サマリ(実装済み) 1. Box/API 境界 - tiny フロントエンドから Superslab への入口: - `hak_tiny_alloc_superslab_box(int class_idx)` に一本化。 - TLS SLL: - slow path を含む呼び出しは `tls_sll_box.h` (`tls_sll_pop(int, void**)` 等) の Box API 経由に統一。 2. shared Superslab pool 実装 - `hakmem_shared_pool.[ch]`: - `SharedSuperSlabPool g_shared_pool` と `shared_pool_init`, `shared_pool_acquire_slab`, `shared_pool_release_slab` を実装。 - SuperSlab を global に管理し、slab 単位で `class_idx` を割当/解放する shared pool 構造を提供。 - `hakmem_tiny_superslab.c`: - `hak_tiny_alloc_superslab_backend_shared(int class_idx)`: - `shared_pool_acquire_slab` により `(ss, slab_idx)` を取得。 - `superslab_init_slab` で未初期化 slab を初期化。 - ジオメトリは `SUPERSLAB_SLAB0_DATA_OFFSET` + `slab_idx * SUPERSLAB_SLAB_USABLE_SIZE` + `used * stride` を使用。 - 単純 bump でブロックを返却。 - `hak_tiny_alloc_superslab_backend_legacy(int class_idx)`: - 旧 per-class `g_superslab_heads` ベースの実装を static backend に封じ込め。 - `hak_tiny_alloc_superslab_box(int class_idx)`: - shared backend → 失敗時に legacy backend へフォールバックする実装に更新。 - `make bench_random_mixed_hakmem`: - ビルドは成功し、shared backend を含む構造的な不整合は解消済み。 3. 現状の問題(2025-11-14 更新) - `bench_random_mixed_hakmem` は SLL(TLS 単方向リスト)有効時に早期 SEGV。 - SLL を無効化(`HAKMEM_TINY_TLS_SLL=0`)すると、shared ON/OFF いずれも安定完走(Throughput 表示)。 - よって、現時点のクラッシュ主因は「共有SS」ではなく「SLL フロント経路の不整合(BASE/USER/next 取り扱い)」である可能性が高い。 以降は、この SEGV を潰し「shared Superslab pool 最小安定版」を完成させるためのデバッグタスクとする。 ## 3. デバッグフェーズの具体タスク ### 3-1. shared backend ON/OFF 制御と原因切り分け 1. shared backend スイッチ導入・確認 - `hak_tiny_alloc_superslab_box(int class_idx)` に環境変数または定数フラグを導入し: - `HAKMEM_TINY_SS_SHARED=0` → legacy backend のみ(回帰確認用) - `HAKMEM_TINY_SS_SHARED=1` → 現行 shared backend(デバッグ対象) - 手順: - legacy 固定で `bench_random_mixed_hakmem` 実行 → SEGV が消えることを確認し、問題が shared 経路に限定されることを保証。 ### 3-2. shared slab メタデータの一貫性検証 2. `shared_pool_acquire_slab` と `hak_tiny_alloc_superslab_backend_shared` の整合確認 - 確認事項: - `class_idx` 割当時に: - `meta->class_idx` が正しく `class_idx` にセットされているか。 - `superslab_init_slab` 呼び出し後、`capacity > 0`, `used == 0`, `freelist == NULL` になっているか。 - `meta->used++` / `total_active_blocks++` の更新が free パスの期待と一致しているか。 - 必要なら: - debug build で `assert(meta->class_idx == class_idx)` 等を追加して早期検出。 3. free/refill 経路との整合性 - 対象ファイル: - `tiny_superslab_free.inc.h` - `hakmem_tiny_free.inc` - `hakmem_tiny_bg_spill.c` - 確認事項: - pointer→SuperSlab→TinySlabMeta 解決ロジックが: - `meta->class_idx` ベースで正しい class を判定しているか。 - shared/legacy の違いに依存せず動作するか。 - 空 slab 判定時に: - `shared_pool_release_slab` を呼ぶ条件と `meta->used == 0` の扱いが矛盾していないか。 - 必要な修正: - shared slab 専用の「空になった slab の返却」パスを導入し、UNASSIGNED への戻しを一元化。 ### 3-3. Superslab registry / LRU / shared pool の連携確認 4. Registry & LRU 連携 - `hakmem_super_registry.c` の: - `hak_super_register`, `hak_super_unregister` - `hak_ss_lru_pop/push` - 確認: - shared pool で確保した SuperSlab も registry に登録されていること。 - LRU 経由再利用時に `class_idx`/slab 割付が破綻していないこと。 - 必要に応じて: - shared pool 管理下の SuperSlab を区別するフラグや、再利用前のメタリセットを追加。 ### 3-4. SEGV の直接解析 5. gdb によるスタックトレース取得(実施) - コマンド例: - `cd hakmem` - `gdb --args ./bench_random_mixed_hakmem` - `run` - `bt` - 結果(抜粋): - `hak_tiny_alloc_fast_wrapper()` 内で SEGV。SLL 無効化で再現しないため、SLL 経路の BASE/USER/next の整合に絞る。 ### 3-5. 安定版 shared Superslab pool の確定 6. 修正後確認 - `HAKMEM_TINY_SS_SHARED=1`(shared 有効)で: - `bench_random_mixed_hakmem` が SEGV 無しで完走すること。 - 簡易的な統計・ログで: - shared Superslab が複数 class で共有されていること。 - メタデータ破綻や異常な解放が発生していないこと。 - これをもって: - 「Phase12 Shared Superslab Pool 最小安定版」が完了。 ### 2-3. TLS / SLL / Refill の整合性確保 **スコープ: `core/hakmem_tiny_refill.inc.h`, `core/hakmem_tiny_tls_ops.h`, `core/hakmem_tiny.c`(局所)** 6. **sll_refill_small_from_ss の Phase12 対応** - 入力: `class_idx`, `max_take` - 動作: - shared pool から該当 `class_idx` の slab を取得 or bind。 - slab の freelist/bump から `max_take` 個を TLS SLL に積む。 - ここでは: - **g_sll_cap_override を参照しない**(将来廃止しやすい形に)。 - cap 計算は `sll_cap_for_class(class_idx, mag_cap)` に集約。 7. **tiny_fast_refill_and_take / TLS SLL 経路の一貫性** - `tiny_fast_refill_and_take` が: - まず TLS SLL / FastCache を見る。 - 足りなければ `sll_refill_small_from_ss` を必ず経由するよう整理(旧経路の枝刈り)。 - ただし: - 既存インラインとの整合性を崩さないよう、**分岐削除は段階的に**行う。 ### 2-4. g_sll_cap_override の段階的無効化(安全版) 8. **参照経路のサニタイズ(非破壊)** - `hakmem_tiny_intel.inc`, `hakmem_tiny_background.inc`, `hakmem_tiny_init.inc` などで: - g_sll_cap_override を書き換える経路を `#if 0` or コメントアウトで停止。 - 配列定義自体はそのまま残し、リンク切れを防ぐ。 - `sll_cap_for_class()` は Phase12 ポリシーに従う実装に置き換える。 - これにより: - 実際の SLL cap は sll_cap_for_class 経由に統一されるが、 - ABI/シンボル互換性は保持される。 9. **ビルド & アセンブリ確認** - `make bench_random_mixed_hakmem` - `gdb -q ./bench_random_mixed_hakmem -ex "disassemble sll_refill_small_from_ss" -ex "quit"` - 確認項目: - g_sll_cap_override 更新経路は実際には使われていない。 - sll_refill_small_from_ss が shared SuperSlab pool を用いる単一ロジックになっている。 ### 2-5. Shared Pool 実装の検証とバグ切り分け 10. **機能検証** - `bench_random_mixed_hakmem` を実行: - SIGSEGV / abort の有無 - ログと `HAKMEM_TINY_SUPERSLAB_TRACE` で shared pool の挙動を確認。 11. **パフォーマンス確認** - 目標: 設計書の期待値に対し、オーダーとして妥当な速度になっているか: - 9M → 70–90M ops/s のレンジを狙う(まずは退行していないことを確認)。 12. **問題発生時の切り分け** - クラッシュ/不正挙動があれば: - まず shared pool 周辺(slab class_idx, freelist 管理, owner/bind/unbind)に絞って原因特定。 - Tiny front-end (bump, SLL, HotMag 等) を疑うのはその後。 --- ## 3. 実装ルール(再確認) - hakmem_tiny.c は write_to_file で全書き換えしない。 - 変更は: - `#if 0` / コメントアウト - 局所的な関数実装差し替え - 新しい shared pool 関数の追加 - 既存呼び出し先の付け替え に限定し、逐次ビルド確認する。 --- ## 4. 直近の変更(2025-11-14 追記) - 定数/APIの復元・宣言不足解消(`SUPERSLAB_LG_*`, 所有権API, active dec, fail-fast スタブ 等)。 - Box 2 drain 境界を `_ss_remote_drain_to_freelist_unsafe()` に一本化。 - `tiny_fast_pop()` が USER を返していた不具合を修正(BASE返却へ)。 - SLL トグルの実効化: - free v2(ヘッダ系)で `g_tls_sll_enable==0` 時は即スローパスへ。 - alloc fast でも SLL 無効時は TLS SLL pop を完全スキップ。 - `tls_sll_box` の capacity > 1<<20 を「無制限」扱いへ(過剰警告を抑制)。 暫定ガイド(shared の検証を先に進めるため) - `HAKMEM_TINY_TLS_SLL=0` で shared ON/OFF の安定動作を確認し、shared 経路の SEGV 有無を切り分ける。 次の一手(SLL ルートの最小修正) 1) SLL push/pop すべての呼び出しを Box API 経由(BASEのみ)に強制。直書き・next手計算を禁止。 2) `tls_sll_box` にデバッグ限定の軽量ガードを追加(slab範囲+stride整合)して最初の破綻ノードを特定。 3) 必要なら一時的に `HAKMEM_TINY_SLL_C03_ONLY=1`(C0–C3 のみ SLL 使用)で範囲を狭め、原因箇所を早期確定。