# 機能設計書 149-利用可能並列度取得

## 概要

本ドキュメントは、libuvのOS情報機能における利用可能な並列処理数取得機能 `uv_available_parallelism()` の設計仕様を定義する。

### 本機能の処理概要

`uv_available_parallelism()` は、現在のプロセスが利用可能な並列処理数（利用可能なCPUコア数）を取得する関数である。CPUアフィニティ制限やcgroup制限を考慮した実効的な値を返す。

**業務上の目的・背景**：マルチスレッドアプリケーションにおいて、最適なワーカースレッド数やスレッドプールサイズを決定するためには、実際に利用可能なCPU並列度を知る必要がある。単純なCPU数ではなく、CPUアフィニティ設定やコンテナ環境でのcgroup制限を考慮した値が必要となる場面がある。本機能はこれらの制限を考慮した実効的な並列処理数を提供する。

**機能の利用シーン**：ワーカースレッドプールのサイズ決定、並列処理の分割数決定、コンテナ環境でのリソース認識、パフォーマンスチューニングなどに使用される。

**主要な処理内容**：
1. プラットフォーム固有の方法で利用可能CPU数を取得する
2. Linuxでは `sched_getaffinity()` を優先的に使用する
3. macOSでは `sysctlbyname()` で hw.activecpu/hw.logicalcpu/hw.ncpu を順に試行する
4. 最低でも1を返すことを保証する

**関連システム・外部連携**：Linux: `sched_getaffinity()`/`sysconf(_SC_NPROCESSORS_ONLN)`、macOS: `sysctlbyname()`、FreeBSD: `cpuset_getaffinity()` 等。

**権限による制御**：一般ユーザー権限で実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_available_parallelism()による並列処理数取得のAPI定義 |

## 機能種別

情報取得処理（システムリソース情報のリードオンリー参照）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （なし） | - | - | パラメータなし | - |

### 入力データソース

OSのCPU情報API。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | unsigned int | 利用可能な並列処理数。最低1が保証される |

### 出力先

呼び出し元への戻り値として返却される。

## 処理フロー

### 処理シーケンス

```
[Linux版]
1. sched_getaffinity(0, sizeof(set), &set) でCPUアフィニティマスク取得
   ├─ 成功 → uv__cpu_count(&set) でセットされたCPU数をカウント
   └─ 失敗 → フォールバック
2. フォールバック: sysconf(_SC_NPROCESSORS_ONLN) でオンラインCPU数取得
3. 最低1を保証して返却

[macOS版]
1. sysctlbyname で以下を順に試行:
   ├─ "hw.activecpu" (アクティブCPU数)
   ├─ "hw.logicalcpu" (論理CPU数)
   └─ "hw.ncpu" (CPU数)
2. 最初に成功し、正の値を返した結果を使用
3. 最低1を保証して返却

[FreeBSD版]
1. cpuset_getaffinity() でCPUアフィニティマスク取得
2. uv__cpu_count(&set) でカウント
3. 最低1を保証して返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_available_parallelism 呼び出し] --> B{プラットフォーム}
    B -->|Linux| C[sched_getaffinity で取得]
    B -->|macOS| D[sysctlbyname で取得]
    B -->|FreeBSD| E[cpuset_getaffinity で取得]
    B -->|Other| F[sysconf SC_NPROCESSORS_ONLN]
    C --> G{取得成功?}
    G -->|No| F
    G -->|Yes| H[CPU数カウント]
    D --> I{hw.activecpu 成功?}
    I -->|No| J{hw.logicalcpu 成功?}
    I -->|Yes| K[値を使用]
    J -->|No| L{hw.ncpu 成功?}
    J -->|Yes| K
    L -->|No| F
    L -->|Yes| K
    E --> H
    F --> M{rc > 0?}
    H --> M
    K --> M
    M -->|Yes| N[rc を返却]
    M -->|No| O[1 を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-149-01 | 最低保証 | 戻り値は最低でも1が保証される | 常時 |
| BR-149-02 | アフィニティ考慮 | Linux/FreeBSDではCPUアフィニティ制限が反映される | Linux/FreeBSD |
| BR-149-03 | フォールバック | Linux版はsched_getaffinity失敗時にsysconfにフォールバック | sched_getaffinity失敗時 |
| BR-149-04 | macOS試行順序 | hw.activecpu → hw.logicalcpu → hw.ncpu の優先順位で試行 | macOS |

### 計算ロジック

Linux: `CPU_COUNT(&set)` でアフィニティマスク内のセットされたビット数をカウント。
macOS: sysctlbynameから直接int値を取得。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | - | 本関数はエラーを返さない。最低1が返る | - |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

OS APIへの1回の呼び出しで完了する。O(1)の定数時間。

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

特になし。CPU数情報にセキュリティ上のリスクはない。

## 備考

- Linux環境ではglibcの `sysconf(_SC_NPROCESSORS_ONLN)` の実装が複雑なため、一貫性のために `sched_getaffinity()` を優先使用する
- コンテナ環境（Docker等）ではCPUアフィニティ制限により物理CPU数より小さい値が返る場合がある
- NetBSD版では `sched_getaffinity_np()` を使用する（POSIX非標準）

---

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

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

### 推奨読解順序

#### Step 1: API宣言を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | API宣言（L1354） |

**読解のコツ**: 戻り値がunsigned int型であり、エラーコードは返さない（最低1保証）点に注目。

#### Step 2: 共通実装フレームワークを理解する

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

**主要処理フロー**:
1. **2051行目**: 関数定義開始。`long rc = -1` で初期化
2. **2054-2064行目**: Linux版 - `sched_getaffinity()` でCPUアフィニティ取得、成功時は `uv__cpu_count(&set)` でカウント
3. **2065-2070行目**: MVS(OS/390)版 - `__get_num_online_cpus()` 使用
4. **2071-2077行目**: FreeBSD版 - `cpuset_getaffinity()` 使用
5. **2078-2084行目**: NetBSD版 - `sched_getaffinity_np()` 使用
6. **2085-2101行目**: macOS版 - `sysctlbyname()` で "hw.activecpu"→"hw.logicalcpu"→"hw.ncpu" を順に試行
7. **2103-2117行目**: OpenBSD版 - `sysctl(CTL_HW, HW_NCPUONLINE)` → `sysctl(CTL_HW, HW_NCPU)` を試行
8. 最終的にrc <= 0の場合は `sysconf(_SC_NPROCESSORS_ONLN)` にフォールバックし、それでも0以下なら1を返す

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

```
uv_available_parallelism()                    [公開API - src/unix/core.c L2051]
    ├─ [Linux] sched_getaffinity()            [OS API]
    │    └─ uv__cpu_count(&set)               [内部関数]
    ├─ [macOS] sysctlbyname()                 [OS API]
    │    └─ "hw.activecpu" / "hw.logicalcpu" / "hw.ncpu"
    ├─ [FreeBSD] cpuset_getaffinity()         [OS API]
    │    └─ uv__cpu_count(&set)
    ├─ [NetBSD] sched_getaffinity_np()        [OS API]
    │    └─ uv__cpu_count(set)
    └─ [フォールバック] sysconf(_SC_NPROCESSORS_ONLN) [POSIX API]
```

### データフロー図

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

（なし） ────▶ uv_available_parallelism()          ────▶ unsigned int (CPU並列度)
               ├─ OS固有APIでCPU数取得                    最低1保証
               ├─ フォールバック: sysconf
               └─ 最低1保証チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 (L1354) |
| core.c | `src/unix/core.c` | ソース | Unix版実装 (L2051-2120+) |
| util.c | `src/win/util.c` | ソース | Windows版実装 |
