# 機能設計書 158-プロセス優先度制御

## 概要

本ドキュメントは、libuvライブラリにおけるuv_os_getpriority()/uv_os_setpriority()関数によるプロセス優先度の取得・設定機能の設計を記述する。

### 本機能の処理概要

uv_os_getpriority()関数は指定したプロセスの優先度（nice値）を取得し、uv_os_setpriority()関数は指定したプロセスの優先度を設定する。クロスプラットフォームでプロセススケジューリング優先度を制御する統一的なAPIを提供する。

**業務上の目的・背景**：バックグラウンドタスクの優先度を下げたり、重要な処理の優先度を上げたりするなど、プロセスのスケジューリング優先度を制御するニーズがある。POSIXのgetpriority()/setpriority()やWindowsのGetPriorityClass()/SetPriorityClass()を統一的にラップする。

**機能の利用シーン**：バックグラウンドジョブの優先度を低く設定、リアルタイム性が求められるプロセスの優先度を高く設定、現在のプロセス優先度の確認、プロセス管理ツールでの優先度表示・制御などに利用される。

**主要な処理内容**：
1. uv_os_getpriority(): 指定PIDのプロセス優先度をgetpriority()/GetPriorityClass()で取得
2. uv_os_setpriority(): 指定PIDのプロセス優先度をsetpriority()/SetPriorityClass()で設定
3. 優先度値の範囲チェック（UV_PRIORITY_HIGHEST ~ UV_PRIORITY_LOW）

**関連システム・外部連携**：
- Unix: getpriority()/setpriority() システムコール
- Windows: OpenProcess()/GetPriorityClass()/SetPriorityClass() Win32 API

**権限による制御**：優先度を上げる（数値を下げる）場合は通常root権限が必要。他プロセスの優先度変更にも権限が必要な場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_os_getpriority()/setpriority()によるプロセス優先度制御のAPI定義 |

## 機能種別

制御処理（プロセススケジューリング優先度の取得・設定）

## 入力仕様

### 入力パラメータ

#### uv_os_getpriority()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pid | uv_pid_t | Yes | 対象プロセスのPID（0は自プロセス） | - |
| priority | int* | Yes | 優先度を格納するポインタ | NULLの場合UV_EINVAL |

#### uv_os_setpriority()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pid | uv_pid_t | Yes | 対象プロセスのPID（0は自プロセス） | - |
| priority | int | Yes | 設定する優先度値 | UV_PRIORITY_HIGHEST(-20) ~ UV_PRIORITY_LOW(19)の範囲外でUV_EINVAL |

### 入力データソース

呼び出し元からの引数。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| *priority (getpriority) | int | 現在の優先度値（-20 ~ 19、Unix nice値に対応） |
| 戻り値 | int | 成功時0、失敗時負のエラーコード |

### 出力先

uv_os_getpriority()の場合、呼び出し元が提供するint変数に書き込む。

## 処理フロー

### 処理シーケンス

```
1. uv_os_getpriority(pid, priority):
   ├─ [QNX] UV_ENOSYSを返す（QNXではプロセスベースの優先度がない）
   ├─ priorityがNULLの場合UV_EINVALを返す
   ├─ errno = 0 に初期化
   ├─ r = getpriority(PRIO_PROCESS, pid) を呼び出し
   ├─ r == -1 かつ errno != 0 の場合エラー
   └─ *priority = r; return 0

2. uv_os_setpriority(pid, priority):
   ├─ [QNX] UV_ENOSYSを返す
   ├─ priority < UV_PRIORITY_HIGHEST または priority > UV_PRIORITY_LOW の場合UV_EINVAL
   ├─ setpriority(PRIO_PROCESS, pid, priority) を呼び出し
   └─ 失敗時はerrnoをlibuvエラーに変換
```

### フローチャート

```mermaid
flowchart TD
    A[uv_os_getpriority] --> B{QNX?}
    B -->|Yes| C[return UV_ENOSYS]
    B -->|No| D{priority == NULL?}
    D -->|Yes| E[return UV_EINVAL]
    D -->|No| F[errno = 0]
    F --> G[r = getpriority PRIO_PROCESS pid]
    G --> H{r == -1 and errno != 0?}
    H -->|Yes| I[return UV__ERR errno]
    H -->|No| J[*priority = r]
    J --> K[return 0]

    L[uv_os_setpriority] --> M{QNX?}
    M -->|Yes| N[return UV_ENOSYS]
    M -->|No| O{priority範囲チェック}
    O -->|範囲外| P[return UV_EINVAL]
    O -->|範囲内| Q[setpriority PRIO_PROCESS pid priority]
    Q --> R{成功?}
    R -->|No| S[return UV__ERR errno]
    R -->|Yes| T[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-158-01 | QNX非サポート | QNXではプロセスベースの優先度がないためUV_ENOSYSを返す | QNXプラットフォーム |
| BR-158-02 | 優先度範囲 | UV_PRIORITY_HIGHEST(-20) ~ UV_PRIORITY_LOW(19)の範囲で指定 | 常時（IBM i PASEでは-10 ~ 39） |
| BR-158-03 | errno初期化 | getpriority()は成功時に-1を返す可能性があるため、事前にerrnoを0に初期化 | uv_os_getpriority() |
| BR-158-04 | 権限要件 | 優先度を上げる場合や他プロセスの優先度変更にはroot権限が必要 | setpriority時 |

### 計算ロジック

特別な計算ロジックはない。Windowsでは優先度値をWindowsのプロセス優先度クラスにマッピングする。

## 優先度定数

| 定数名 | 通常値 | IBM i PASE値 | 説明 |
|--------|--------|-------------|------|
| UV_PRIORITY_LOW | 19 | 39 | 最低優先度 |
| UV_PRIORITY_BELOW_NORMAL | 10 | 15 | 標準以下 |
| UV_PRIORITY_NORMAL | 0 | 0 | 標準 |
| UV_PRIORITY_ABOVE_NORMAL | -7 | -4 | 標準以上 |
| UV_PRIORITY_HIGH | -14 | -7 | 高優先度 |
| UV_PRIORITY_HIGHEST | -20 | -10 | 最高優先度 |

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

該当なし（データベース操作は行わない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 引数不正 | priorityポインタがNULL、または優先度値が範囲外 | 有効な引数を渡す |
| UV_ENOSYS | 非サポート | QNXプラットフォーム | プラットフォーム制約として受け入れる |
| UV_EPERM | 権限不足 | 優先度を上げる権限がない | root権限で実行 |
| UV_ESRCH | プロセス不在 | 指定PIDのプロセスが存在しない | PIDを確認 |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

軽量な処理であり即座に完了する。

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

プロセス優先度の変更には適切な権限が必要。不正に優先度を上げるとシステム全体のパフォーマンスに影響する可能性がある。setpriority()はEPERMエラーで権限チェックを行う。

## 備考

- getpriority()の戻り値は正当に-1になる可能性がある（nice値-1のプロセス）。そのため、エラー判定にはerrnoを事前に0に初期化し、戻り値が-1かつerrnoが0でない場合のみエラーとする。
- IBM i PASEでは優先度範囲が通常のUnixと異なる（-10 ~ 39）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | 優先度定数の定義（1323-1338行目） |
| 1-2 | uv.h | `include/uv.h` | API宣言（1340-1341行目） |

**読解のコツ**: 1323-1338行目でプラットフォーム別（__PASE__かそれ以外）に優先度定数が定義されている。IBM i PASEでの値が通常と異なることを確認すること。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | uv_os_getpriority()/uv_os_setpriority()のUnix実装 |

**主要処理フロー**:
- **1683行目**: `uv_os_getpriority()` 関数エントリーポイント
- **1684-1686行目**: QNXの場合UV_ENOSYSを返す
- **1690-1691行目**: priorityのNULLチェック
- **1693行目**: `errno = 0;` - errno初期化（重要）
- **1694行目**: `r = getpriority(PRIO_PROCESS, (int) pid);`
- **1696-1697行目**: エラー判定（r == -1 かつ errno != 0）
- **1705行目**: `uv_os_setpriority()` 関数エントリーポイント
- **1710-1711行目**: 優先度範囲チェック
- **1713行目**: `setpriority(PRIO_PROCESS, (int) pid, priority)`

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | Windows版uv_os_getpriority()/uv_os_setpriority()実装 |

**主要処理フロー**:
- **1443行目**: `uv_os_getpriority()` Windows版 - GetPriorityClass()使用
- **1482行目**: `uv_os_setpriority()` Windows版 - SetPriorityClass()使用

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

```
uv_os_getpriority(pid, priority)
    |
    +-- [Unix] getpriority(PRIO_PROCESS, pid)
    +-- [QNX] return UV_ENOSYS
    +-- [Windows] OpenProcess() → GetPriorityClass()

uv_os_setpriority(pid, priority)
    |
    +-- [Unix] setpriority(PRIO_PROCESS, pid, priority)
    +-- [QNX] return UV_ENOSYS
    +-- [Windows] OpenProcess() → SetPriorityClass()
```

### データフロー図

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

pid (uv_pid_t)          ----> uv_os_getpriority()      ---> *priority (int)
priority (int*)               +-- getpriority /              戻り値: 0 or error
                                  GetPriorityClass

pid (uv_pid_t)          ----> uv_os_setpriority()      ---> 戻り値: 0 or error
priority (int)                +-- setpriority /
                                  SetPriorityClass
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | 優先度定数定義、API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix系uv_os_getpriority()/uv_os_setpriority()実装 |
| util.c | `src/win/util.c` | ソース | Windows版uv_os_getpriority()/uv_os_setpriority()実装 |
