# 機能設計書 129-スレッド優先度制御

## 概要

本ドキュメントは、libuvが提供するスレッド優先度制御機能 `uv_thread_setpriority()` / `uv_thread_getpriority()` の設計仕様を記述する。スレッドのスケジューリング優先度を取得・設定するためのクロスプラットフォームAPIである。

### 本機能の処理概要

**業務上の目的・背景**：マルチスレッドアプリケーションにおいて、特定のスレッドに高い優先度を与えてリアルタイム性を確保したり、バックグラウンド処理の優先度を下げてフォアグラウンド処理への影響を最小化する必要がある。本機能はプラットフォームごとに異なるスレッド優先度制御のAPIを抽象化し、5段階の優先度レベル（HIGHEST/ABOVE_NORMAL/NORMAL/BELOW_NORMAL/LOWEST）で統一的に制御できるようにしている。

**機能の利用シーン**：リアルタイム処理スレッドの優先度引き上げ、バックグラウンドGC/圧縮処理の優先度引き下げ、CPU集約処理の優先度制御に使用される。

**主要な処理内容**：
1. `uv_thread_getpriority()`: 指定スレッドの現在の優先度を取得する
2. `uv_thread_setpriority()`: 指定スレッドの優先度を5段階のレベルで設定する

**関連システム・外部連携**：POSIX pthread_getschedparam()/pthread_setschedparam()、Linux getpriority()/setpriority()（nice値）、Windows GetThreadPriority()/SetThreadPriority()。

**権限による制御**：Linuxでは優先度の引き上げにroot権限またはCAP_SYS_NICEが必要。Windowsでは一部の優先度設定に管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | スレッド | 主機能 | uv_thread_setpriority()/getpriority()によるスレッド優先度制御のAPI定義 |

## 機能種別

リソース管理（スレッド優先度制御）

## 入力仕様

### 入力パラメータ

#### uv_thread_getpriority()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tid | uv_thread_t | Yes | 対象スレッドID（値渡し） | - |
| priority | int* | Yes | 優先度の格納先 | NULL不可 |

#### uv_thread_setpriority()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tid | uv_thread_t | Yes | 対象スレッドID（値渡し） | - |
| priority | int | Yes | 設定する優先度 | UV_THREAD_PRIORITY_LOWEST(-2)〜UV_THREAD_PRIORITY_HIGHEST(2) |

### 入力データソース

ユーザーからの関数呼び出しパラメータ。優先度は以下の列挙値を使用:
- UV_THREAD_PRIORITY_HIGHEST (2)
- UV_THREAD_PRIORITY_ABOVE_NORMAL (1)
- UV_THREAD_PRIORITY_NORMAL (0)
- UV_THREAD_PRIORITY_BELOW_NORMAL (-1)
- UV_THREAD_PRIORITY_LOWEST (-2)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 0:成功、負値:エラーコード |
| *priority | int | 取得された優先度値（getpriority時） |

### 出力先

関数の戻り値とpriorityポインタ経由で返却。

## 処理フロー

### 処理シーケンス

```
■ uv_thread_getpriority()（Unix版）:
1. priorityのNULLチェック
2. pthread_getschedparam()でスケジューリングポリシーとパラメータを取得
3. Linuxの場合:
   └─ SCHED_OTHERポリシーかつ自スレッドの場合:
      getpriority(PRIO_PROCESS, gettid())でnice値を取得
   └─ それ以外: param.sched_priorityを返却
4. Linux以外: param.sched_priorityを返却

■ uv_thread_setpriority()（Unix版）:
1. 優先度範囲チェック（LOWEST〜HIGHEST）
2. pthread_getschedparam()で現在のポリシーを取得
3. Linuxの場合:
   └─ SCHED_OTHERかつ自スレッド: set_nice_for_calling_thread()で
      nice値を設定（priority × -2）
4. sched_get_priority_min/max()でポリシーの優先度範囲を取得
5. 5段階の優先度をOS優先度範囲にマッピング
6. pthread_setschedparam()で設定

■ Windows版:
1. getpriority: GetThreadPriority()で取得
2. setpriority: priorityに応じたWindowsスレッド優先度定数でSetThreadPriority()
```

### フローチャート

```mermaid
flowchart TD
    A[uv_thread_setpriority呼び出し] --> B{優先度範囲チェック}
    B -->|範囲外| Z[UV_EINVAL返却]
    B -->|OK| C[pthread_getschedparam]
    C --> D{Linux && SCHED_OTHER?}
    D -->|Yes| E[set_nice_for_calling_thread]
    D -->|No| F[sched_get_priority_min/max]
    F --> G[5段階→OS優先度マッピング]
    G --> H[pthread_setschedparam]
    E --> I[結果返却]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-129-1 | 5段階優先度 | HIGHEST(2)/ABOVE_NORMAL(1)/NORMAL(0)/BELOW_NORMAL(-1)/LOWEST(-2)の5段階 | 常時 |
| BR-129-2 | Linux nice値マッピング | SCHED_OTHER時はnice値に変換: nice = 0 - priority * 2 | Linux SCHED_OTHER |
| BR-129-3 | OS優先度マッピング | 5段階をOSの優先度範囲（min〜max）に線形マッピング | SCHED_OTHER以外 |
| BR-129-4 | Windows優先度マッピング | 5段階をTHREAD_PRIORITY_HIGHEST/ABOVE_NORMAL/NORMAL/BELOW_NORMAL/LOWESTに直接マッピング | Windows |
| BR-129-5 | 自スレッド限定（Linux） | Linux SCHED_OTHERの場合、nice値設定は自スレッドに限定 | Linux SCHED_OTHER |

### 計算ロジック

Linux nice値マッピング:
```
nice = 0 - priority * 2
例: HIGHEST(2) → nice = -4, LOWEST(-2) → nice = 4
```

OS優先度範囲マッピング:
```
range = max - min
HIGHEST: max
ABOVE_NORMAL: min + range * 3/4
NORMAL: min + range / 2
BELOW_NORMAL: min + range * 1/4
LOWEST: min
```

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

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータエラー | priority==NULL（get時）、または優先度が範囲外 | パラメータを修正 |
| UV_EPERM | 権限不足 | 優先度設定権限なし（Linuxのnice値引き下げ等） | root権限またはCAP_SYS_NICEを付与 |
| UV_ESRCH | スレッド不在 | 指定スレッドが存在しない（Windows） | スレッドIDを確認 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

優先度変更はシステムコールを伴うが、即座に完了する。

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

- 優先度の引き上げには特権が必要。不正な優先度操作はシステム全体に影響を与えうる
- 高優先度スレッドが無限ループに陥ると他のスレッドが実行できなくなる

## 備考

- Linuxでは、デフォルトスケジューリングポリシー（SCHED_OTHER）の場合、pthread APIの優先度は常に0であるため、nice値で代用する設計になっている
- GNU Hurd（__GNU__）では本機能は非対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **1343-1349行目**: UV_THREAD_PRIORITY_*列挙値の定義 |
| 1-2 | uv.h | `include/uv.h` | **1351-1352行目**: `uv_thread_getpriority()`/`uv_thread_setpriority()`の関数シグネチャ。tidは値渡し |

**読解のコツ**: tidがポインタではなく値渡しであることに注意。これはアフィニティ制御のAPIとは異なる。

#### Step 2: Unix/Linux実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | **1726-1754行目**: `uv_thread_getpriority()`。pthread_getschedparam()で取得後、Linux SCHED_OTHERの場合はgetpriority()でnice値を取得 |
| 2-2 | core.c | `src/unix/core.c` | **1757-1770行目**: `set_nice_for_calling_thread()`。優先度をnice値に変換しsetpriority()で設定 |
| 2-3 | core.c | `src/unix/core.c` | **1777-1819行目以降**: `uv_thread_setpriority()`。ポリシー取得→Linux nice値特殊処理→OS優先度範囲マッピング→pthread_setschedparam() |

**主要処理フロー（getpriority Linux版）**:
- **1737行目**: pthread_getschedparam()で現在のポリシーとパラメータを取得
- **1742-1749行目**: SCHED_OTHERかつ自スレッドの場合、getpriority()でnice値を取得
- **1752行目**: その他の場合、param.sched_priorityを返却

#### Step 3: Windows実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | **1515-1532行目**: Windows版`uv_thread_getpriority()`。GetThreadPriority()で取得 |
| 3-2 | util.c | `src/win/util.c` | **1534-1566行目**: Windows版`uv_thread_setpriority()`。switch文でlibuvの5段階→Windows優先度定数にマッピングしSetThreadPriority() |

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

```
uv_thread_getpriority() [src/unix/core.c:1726]
    │
    +── pthread_getschedparam() ポリシー・パラメータ取得
    └── getpriority(PRIO_PROCESS, gettid()) ※Linux SCHED_OTHER時

uv_thread_setpriority() [src/unix/core.c:1777]
    │
    +── pthread_getschedparam() 現在ポリシー取得
    +── set_nice_for_calling_thread() ※Linux SCHED_OTHER時
    │       └── setpriority(PRIO_PROCESS, gettid(), nice)
    +── sched_get_priority_min() / sched_get_priority_max()
    └── pthread_setschedparam()

uv_thread_getpriority() [src/win/util.c:1515]
    └── GetThreadPriority()

uv_thread_setpriority() [src/win/util.c:1534]
    └── SetThreadPriority()
```

### データフロー図

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

tid, priority ──────▶ uv_thread_setpriority()
                          │
                     [5段階→OS優先度変換]
                          │
                     [OS API呼び出し] ──▶ int (0 or error)

tid, *priority ─────▶ uv_thread_getpriority()
                          │
                     [OS API呼び出し]
                          │
                     [OS優先度取得] ──▶ *priority (int)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言と優先度列挙値定義 |
| core.c | `src/unix/core.c` | ソース | Unix/Linux実装 |
| util.c | `src/win/util.c` | ソース | Windows実装 |
