# 機能設計書 89-libpthread（スレッドライブラリ）

## 概要

本ドキュメントは、FreeBSDのPOSIXスレッドライブラリ（libthr/libpthread）の機能設計を記述する。libthrはFreeBSDのネイティブPOSIXスレッド実装であり、1:1スレッドモデル（ユーザスレッドとカーネルスレッドが1対1対応）に基づくマルチスレッドプログラミングの基盤ライブラリである。

### 本機能の処理概要

**業務上の目的・背景**：POSIXスレッドライブラリはマルチスレッドプログラミングの標準APIを提供する。Webサーバ、データベース、GUI アプリケーション等の並行処理を実現し、マルチコアCPUの性能を活用するために不可欠な基盤である。FreeBSDではlibthrが唯一のスレッドライブラリ実装として位置づけられている。

**機能の利用シーン**：マルチスレッドアプリケーションの開発・実行。Webサーバ（Apache/Nginx）のワーカースレッド、データベースの並行クエリ処理、GUIアプリケーションのバックグラウンド処理等。

**主要な処理内容**：
1. スレッド管理: pthread_create/pthread_join/pthread_detach/pthread_exit - スレッドの生成・合流・切離・終了
2. ミューテックス: pthread_mutex_init/lock/unlock/destroy - 相互排他制御。適応的スピン(MUTEX_ADAPTIVE_SPINS=2000)をサポート
3. 条件変数: pthread_cond_init/wait/signal/broadcast - スレッド間の条件同期
4. 読み書きロック: pthread_rwlock_init/rdlock/wrlock/unlock - 読者-書者問題の解決
5. バリア: pthread_barrier_init/wait - 複数スレッドの同期ポイント
6. スレッドローカルストレージ: pthread_key_create/getspecific/setspecific
7. セマフォ: sem_init/wait/post - カウンティングセマフォ
8. スレッド属性: pthread_attr_init/setdetachstate/setstacksize等

**関連システム・外部連携**：カーネルのスレッドサブシステム（thr_new/thr_exit/thr_kill等のシステムコール）、umtxカーネルプリミティブ（ユーザ空間ミューテックス）、libc（スレッドスタブとの連携）。

**権限による制御**：一般ユーザで使用可能。リアルタイムスケジューリングポリシー（SCHED_FIFO/SCHED_RR）の設定にはroot権限が必要。

## 関連画面

該当なし（ライブラリのため画面は存在しない）

## 機能種別

ランタイムライブラリ / スレッド同期プリミティブ

## 入力仕様

### 入力パラメータ

| 関数群 | 代表的API | 説明 |
|--------|---------|------|
| スレッド生成 | pthread_create(thread, attr, start_routine, arg) | 新スレッド生成 |
| スレッド合流 | pthread_join(thread, retval) | スレッド終了待機 |
| ミューテックス | pthread_mutex_lock(mutex) | 排他ロック取得 |
| 条件変数 | pthread_cond_wait(cond, mutex) | 条件待機 |
| 読み書きロック | pthread_rwlock_rdlock(rwlock) | 読み取りロック取得 |

### 入力データソース

アプリケーションからのAPI呼出引数。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 関数戻り値 | int | 0=成功、非0=エラー番号（POSIX規約） |
| スレッドID | pthread_t | 生成されたスレッドの識別子 |

### 出力先

呼出側のメモリ空間。

## 処理フロー

### 処理シーケンス（pthread_create）

```
1. スレッド属性解決
   └─ attr引数から属性取得（デフォルト属性またはカスタム属性）
2. スタック確保
   └─ create_stack(): mmap(2)でスレッドスタック領域確保
3. スレッド構造体初期化
   └─ struct pthread構造体のフィールド初期化
4. カーネルスレッド生成
   └─ thr_new(2)システムコールでカーネルスレッド生成
5. スレッド開始
   └─ thread_start(): ユーザ指定のstart_routineを実行
6. スレッドリスト登録
   └─ _thread_listにスレッドを追加
```

### フローチャート

```mermaid
flowchart TD
    A[pthread_create呼出] --> B[スレッド属性解決]
    B --> C[create_stack: スタック確保]
    C --> D[struct pthread初期化]
    D --> E[thr_new: カーネルスレッド生成]
    E --> F{生成成功?}
    F -->|Yes| G[thread_start: 開始関数実行]
    F -->|No| H[エラー返却]
    G --> I[start_routine実行]
    I --> J[pthread_exit: スレッド終了]
    J --> K[リソース解放・GCリスト追加]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-89-01 | 1:1スレッドモデル | ユーザスレッドとカーネルスレッドが1対1に対応 | 常時 |
| BR-89-02 | 適応的スピン | ミューテックスのロック取得前にMUTEX_ADAPTIVE_SPINS(2000)回のスピン試行 | 適応的ミューテックス使用時 |
| BR-89-03 | スレッドGC | 終了したスレッドは_thread_gc_listに追加され遅延解放 | スレッド終了時 |
| BR-89-04 | 初期スレッド | _thr_initialがメインスレッドを表す | ライブラリ初期化時 |
| BR-89-05 | スケジューリング優先度 | FIFO/OTHER/RRの3ポリシーに対応。OTHERのデフォルト優先度は63 | スレッド属性設定時 |
| BR-89-06 | umtxプリミティブ | カーネルのユーザ空間ミューテックス(umtx)でロックの効率的なブロッキングを実現 | mutex/cond/rwlock使用時 |

### 計算ロジック

適応的スピン: mutex取得時にまずMUTEX_ADAPTIVE_SPINS(2000)回のtrylock2を実行。スピン中にロックが解放されればカーネルブロッキングなしで取得可能。スピン後もロック取得できない場合はumtx経由でカーネルブロッキングに移行。

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EAGAIN | リソース不足 | スレッド生成に必要なリソース不足 | エラー番号返却 |
| EINVAL | 不正属性 | 無効なスレッド属性指定 | エラー番号返却 |
| EDEADLK | デッドロック検出 | 自スレッドが保持するmutexの再ロック | エラー番号返却 |
| EPERM | 権限エラー | リアルタイムスケジューリング設定 | エラー番号返却 |

### リトライ仕様

リトライはライブラリ内部では行わない。呼出側の責任。

## トランザクション仕様

該当なし（各プリミティブ操作は原子的に実行）

## パフォーマンス要件

- 適応的スピン（2000回）によるmutexロックの高速取得
- umtxカーネルプリミティブによる効率的なスレッドブロッキング
- off-page mutexサポート（sizeof(pthread_mutex) <= THR_PAGE_SIZE_MIN）

## セキュリティ考慮事項

- スタックオーバーフロー検出のためのガードページ設定
- スレッドキャンセルの安全性（キャンセルポイントの適切な配置）

## 備考

- libthrはFreeBSD 7.0から唯一のPOSIXスレッドライブラリ（旧libkse/libc_rは廃止）
- _thread_active_threads変数でアクティブスレッド数を追跡（初期値1:メインスレッド）
- _thr_priorities[3]配列でFIFO/OTHER/RRの3ポリシーの優先度範囲を管理
- pthread.mapでシンボルバージョニングを管理
- plockstat.dでDTraceプローブを定義

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

libthrの中核データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | thr_private.h | `lib/libthr/thread/thr_private.h`（推定） | struct pthread定義、同期プリミティブ構造体、グローバルリスト |

**読解のコツ**: `struct pthread`がスレッドの全状態を保持する中核構造体。`pthreadlist`（TAILQ）でスレッドリストを管理。`struct urwlock`がユーザ空間読み書きロック。

#### Step 2: ライブラリ初期化

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | thr_init.c | `lib/libthr/thread/thr_init.c` | ライブラリ初期化。_thr_initial設定、優先度テーブル、グローバルリスト初期化 |

**主要処理フロー**:
1. **64行目**: _usrstack（ユーザスタックポインタ）
2. **65行目**: _thr_initial（メインスレッド構造体ポインタ）
3. **69行目**: _thread_list = TAILQ_HEAD_INITIALIZER（スレッドリスト）
4. **70行目**: _thread_gc_list = TAILQ_HEAD_INITIALIZER（GCリスト）
5. **71行目**: _thread_active_threads = 1（初期アクティブスレッド数）
6. **75-79行目**: _thr_priorities[3]（FIFO/OTHER/RRの優先度範囲）

#### Step 3: スレッド生成

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | thr_create.c | `lib/libthr/thread/thr_create.c` | _pthread_create()関数。スタック確保、カーネルスレッド生成 |

**主要処理フロー**:
- **50行目**: create_stack()関数宣言
- **51行目**: thread_start()関数宣言
- **53行目**: __thr_new_flags = THR_C_RUNTIME
- **55行目**: __weak_reference(_pthread_create, pthread_create)
- **57-60行目**: _pthread_create()関数シグネチャ

#### Step 4: ミューテックス実装

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | thr_mutex.c | `lib/libthr/thread/thr_mutex.c` | ミューテックス実装。適応的スピン、umtxカーネル連携 |

**主要処理フロー**:
- **53-54行目**: _Static_assert: pthread_mutexがTHR_PAGE_SIZE_MIN以下であること
- **60行目**: MUTEX_ADAPTIVE_SPINS = 2000（適応的スピン回数）

#### Step 5: その他の同期プリミティブ

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | thr_cond.c | `lib/libthr/thread/thr_cond.c` | 条件変数実装 |
| 5-2 | thr_rwlock.c | `lib/libthr/thread/thr_rwlock.c` | 読み書きロック実装 |
| 5-3 | thr_barrier.c | `lib/libthr/thread/thr_barrier.c` | バリア実装 |
| 5-4 | thr_sem.c | `lib/libthr/thread/thr_sem.c` | セマフォ実装 |

#### Step 6: カーネル連携

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | thr_umtx.c | `lib/libthr/thread/thr_umtx.c` | umtxカーネルプリミティブのラッパー |
| 6-2 | thr_syscalls.c | `lib/libthr/thread/thr_syscalls.c` | システムコールラッパー（キャンセルポイント対応） |

### プログラム呼び出し階層図

```
pthread_create()
    |
    +-- _pthread_create()           # 弱参照経由
    |       +-- create_stack()      # mmap(2)でスタック確保
    |       +-- pthread初期化       # struct pthread設定
    |       +-- thr_new(2)          # カーネルスレッド生成
    |       +-- thread_start()      # ユーザ関数呼出
    |               +-- start_routine()
    |               +-- pthread_exit()

pthread_mutex_lock()
    |
    +-- trylock2() x MUTEX_ADAPTIVE_SPINS  # 適応的スピン
    +-- thr_umtx: _umtx_op()              # カーネルブロッキング

pthread_cond_wait()
    |
    +-- mutex_unlock()
    +-- thr_umtx: _umtx_op(UMTX_OP_WAIT) # カーネル待機
    +-- mutex_lock()
```

### データフロー図

```
[入力]                          [処理]                          [出力]

アプリケーション呼出 ──> libthr API ──> カーネルスレッド操作
                         スレッド管理       thr_new/thr_exit
                         同期プリミティブ   umtx操作
                         属性管理          スケジューリング

カーネル応答 ──> libthr ──> アプリケーション
                 スレッドID返却
                 ロック取得結果
                 条件通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| thr_init.c | `lib/libthr/thread/thr_init.c` | ソース | ライブラリ初期化 |
| thr_create.c | `lib/libthr/thread/thr_create.c` | ソース | スレッド生成 |
| thr_exit.c | `lib/libthr/thread/thr_exit.c` | ソース | スレッド終了 |
| thr_join.c | `lib/libthr/thread/thr_join.c` | ソース | スレッド合流 |
| thr_mutex.c | `lib/libthr/thread/thr_mutex.c` | ソース | ミューテックス |
| thr_cond.c | `lib/libthr/thread/thr_cond.c` | ソース | 条件変数 |
| thr_rwlock.c | `lib/libthr/thread/thr_rwlock.c` | ソース | 読み書きロック |
| thr_barrier.c | `lib/libthr/thread/thr_barrier.c` | ソース | バリア |
| thr_sem.c | `lib/libthr/thread/thr_sem.c` | ソース | セマフォ |
| thr_umtx.c | `lib/libthr/thread/thr_umtx.c` | ソース | umtxカーネルプリミティブ |
| thr_umtx.h | `lib/libthr/thread/thr_umtx.h` | ヘッダ | umtx宣言 |
| thr_sig.c | `lib/libthr/thread/thr_sig.c` | ソース | シグナル処理 |
| thr_cancel.c | `lib/libthr/thread/thr_cancel.c` | ソース | キャンセル処理 |
| thr_stack.c | `lib/libthr/thread/thr_stack.c` | ソース | スタック管理 |
| thr_attr.c | `lib/libthr/thread/thr_attr.c` | ソース | スレッド属性 |
| thr_kern.c | `lib/libthr/thread/thr_kern.c` | ソース | カーネル連携 |
| thr_syscalls.c | `lib/libthr/thread/thr_syscalls.c` | ソース | システムコールラッパー |
| thr_list.c | `lib/libthr/thread/thr_list.c` | ソース | スレッドリスト管理 |
| thr_spec.c | `lib/libthr/thread/thr_spec.c` | ソース | スレッドローカルストレージ |
| thr_fork.c | `lib/libthr/thread/thr_fork.c` | ソース | fork対応 |
| thr_affinity.c | `lib/libthr/thread/thr_affinity.c` | ソース | CPU親和性 |
| pthread.map | `lib/libthr/pthread.map` | 設定 | シンボルバージョニング |
| plockstat.d | `lib/libthr/plockstat.d` | DTrace | DTraceプローブ定義 |
| Makefile | `lib/libthr/Makefile` | ビルド設定 | libthrビルド設定 |
