# 機能設計書 155-リソース使用状況取得

## 概要

本ドキュメントは、libuvライブラリにおけるuv_getrusage()/uv_getrusage_thread()関数によるリソース使用状況取得機能の設計を記述する。

### 本機能の処理概要

uv_getrusage()関数はプロセス全体の、uv_getrusage_thread()関数は現在のスレッドのリソース使用状況（CPU時間、メモリ、ページフォルト、コンテキストスイッチなど）をクロスプラットフォームで取得する機能を提供する。

**業務上の目的・背景**：アプリケーションのパフォーマンス分析やリソース消費監視において、CPU使用時間、メモリ使用量、ページフォルト回数などの詳細なリソース情報は不可欠である。POSIXのgetrusage()やWindows固有のAPIを統一的にラップすることで、クロスプラットフォームなプロファイリング・監視を実現する。

**機能の利用シーン**：アプリケーションのパフォーマンスプロファイリング、リソース使用量の監視・ログ出力、CPU使用率の計算、メモリリーク検出の補助、スレッドごとのリソース消費分析などに利用される。

**主要な処理内容**：
1. uv_getrusage(): getrusage(RUSAGE_SELF)を呼び出しプロセス全体のリソース情報を取得
2. uv_getrusage_thread(): プラットフォーム固有のAPIでスレッド単位のリソース情報を取得
3. プラットフォーム間でのru_maxrss単位の正規化（macOS:バイト→KB、Solaris:ページ→KB）
4. uv_rusage_t構造体への各フィールドのコピー

**関連システム・外部連携**：
- Unix: getrusage()システムコール（RUSAGE_SELF, RUSAGE_THREAD, RUSAGE_LWP）
- macOS: thread_info(THREAD_BASIC_INFO) Mach API
- Windows: GetProcessTimes(), GetProcessMemoryInfo(), GetThreadTimes()

**権限による制御**：特別な権限は不要。一般ユーザー権限で実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_getrusage()/getrusage_thread()によるリソース使用状況取得のAPI定義 |

## 機能種別

データ取得処理（プロセス/スレッドリソース使用情報の読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rusage | uv_rusage_t* | Yes | リソース使用情報を格納する構造体へのポインタ | 有効なポインタが必要 |

### 入力データソース

OSカーネルからリソース使用情報を取得する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ru_utime | uv_timeval_t | ユーザーCPU時間 |
| ru_stime | uv_timeval_t | システムCPU時間 |
| ru_maxrss | uint64_t | 最大常駐セットサイズ（KB） |
| ru_ixrss | uint64_t | 共有メモリサイズ（積算） |
| ru_idrss | uint64_t | 非共有データサイズ（積算） |
| ru_isrss | uint64_t | 非共有スタックサイズ（積算） |
| ru_minflt | uint64_t | ソフトページフォルト回数 |
| ru_majflt | uint64_t | ハードページフォルト回数 |
| ru_nswap | uint64_t | スワップ回数 |
| ru_inblock | uint64_t | ブロック入力操作回数 |
| ru_oublock | uint64_t | ブロック出力操作回数 |
| ru_msgsnd | uint64_t | IPC送信メッセージ数 |
| ru_msgrcv | uint64_t | IPC受信メッセージ数 |
| ru_nsignals | uint64_t | 受信シグナル数 |
| ru_nvcsw | uint64_t | 自発的コンテキストスイッチ回数 |
| ru_nivcsw | uint64_t | 非自発的コンテキストスイッチ回数 |
| 戻り値 | int | 成功時0、失敗時負のエラーコード |

### 出力先

呼び出し元が提供するuv_rusage_t構造体に書き込む。

## 処理フロー

### 処理シーケンス

```
1. uv_getrusage():
   └─ uv__getrusage(RUSAGE_SELF, rusage) を呼び出し
       ├─ getrusage(RUSAGE_SELF, &usage) を呼び出し
       ├─ uv_rusage_t構造体に各フィールドをコピー
       └─ ru_maxrssの単位正規化
           ├─ macOS: バイト→KB（/= 1024）
           └─ Solaris: ページ→KB（*= getpagesize()/1024）

2. uv_getrusage_thread():
   ├─ [macOS] thread_info(THREAD_BASIC_INFO) でスレッドCPU時間取得
   │      └─ memset()で構造体を0初期化後、utime/stimeのみ設定
   ├─ [RUSAGE_LWP対応] uv__getrusage(RUSAGE_LWP, rusage)
   ├─ [RUSAGE_THREAD対応] uv__getrusage(RUSAGE_THREAD, rusage)
   └─ [非対応] UV_ENOTSUP を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_getrusage] --> B[uv__getrusage RUSAGE_SELF]
    B --> C[getrusage 呼び出し]
    C --> D{成功?}
    D -->|No| E[return UV__ERR errno]
    D -->|Yes| F[各フィールドコピー]
    F --> G{macOS?}
    G -->|Yes| H[ru_maxrss /= 1024]
    G -->|No| I{Solaris?}
    I -->|Yes| J[ru_maxrss *= pagesize/1024]
    I -->|No| K[そのまま]
    H --> L[return 0]
    J --> L
    K --> L

    M[uv_getrusage_thread] --> N{プラットフォーム}
    N -->|macOS| O[thread_info THREAD_BASIC_INFO]
    N -->|RUSAGE_LWP| P[uv__getrusage RUSAGE_LWP]
    N -->|RUSAGE_THREAD| Q[uv__getrusage RUSAGE_THREAD]
    N -->|その他| R[return UV_ENOTSUP]
    O --> S[utime/stimeのみ設定]
    S --> T[return 0]
    P --> T
    Q --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-155-01 | ru_maxrss正規化 | macOSではバイト→KB、Solarisではページ→KBに変換 | 各プラットフォーム |
| BR-155-02 | macOSスレッドリソース | macOSではMach APIを使用し、CPU時間のみ取得可能 | macOSプラットフォーム |
| BR-155-03 | MVS/Haiku例外 | z/OS(MVS)とHaikuではru_maxrss等のフィールドが取得できない | MVS/Haikuプラットフォーム |
| BR-155-04 | 非対応プラットフォーム | RUSAGE_LWPもRUSAGE_THREADもサポートしない環境ではUV_ENOTSUP | 一部環境 |

### 計算ロジック

- macOS: `rusage->ru_maxrss /= 1024` （バイトからKBへ変換）
- Solaris: `rusage->ru_maxrss *= getpagesize() / 1024` （ページからKBへ変換）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV__ERR(errno) | システムエラー | getrusage()システムコール失敗 | OSの状態を確認 |
| UV_EINVAL | 引数不正 | macOSでthread_info()失敗 | スレッド状態を確認 |
| UV_ENOTSUP | 未サポート | スレッド単位リソース取得非対応環境 | uv_getrusage()（プロセス単位）を使用 |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

単一のシステムコール呼び出しであり、即座に完了する。

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

リソース使用情報は自プロセスのものであり、セキュリティ上の問題は通常ない。

## 備考

- uv_rusage_t構造体はPOSIXのrusage構造体をモデルにしているが、フィールドの型がuint64_tに統一されている。
- macOSのuv_getrusage_thread()はMach APIのthread_info()を使用するため、CPU時間のみ取得でき、メモリやページフォルト等の情報は取得できない。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_rusage_t構造体の定義（1291-1308行目） |

**読解のコツ**: uv_rusage_t（1291-1308行目）はuv_timeval_t型のCPU時間2フィールドとuint64_t型の14フィールドで構成される。POSIXのrusage構造体と対応関係を理解すること。

#### Step 2: 内部実装（共通ヘルパー）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | uv__getrusage()内部ヘルパー関数 |

**主要処理フロー**:
- **1097行目**: `static int uv__getrusage(int who, uv_rusage_t* rusage)` 定義
- **1100行目**: getrusage()システムコール呼び出し
- **1103-1107行目**: CPU時間のコピー
- **1109-1124行目**: 各統計フィールドのコピー（MVS/Haiku除外）
- **1126-1132行目**: ru_maxrssの単位正規化（macOS: /1024、Solaris: *pagesize/1024）

#### Step 3: パブリックAPI実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.c | `src/unix/core.c` | uv_getrusage()およびuv_getrusage_thread()実装 |

**主要処理フロー**:
- **1139-1141行目**: `uv_getrusage()` - RUSAGE_SELFでuv__getrusageを呼び出し
- **1144-1180行目**: `uv_getrusage_thread()` - プラットフォーム分岐
  - **1145-1172行目**: macOS版 - thread_info(THREAD_BASIC_INFO)
  - **1174-1175行目**: RUSAGE_LWP対応（Solaris等）
  - **1176-1177行目**: RUSAGE_THREAD対応（Linux等）
  - **1179行目**: 非対応環境ではUV_ENOTSUP

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

```
uv_getrusage(rusage)
    └─ uv__getrusage(RUSAGE_SELF, rusage)
           ├─ getrusage(RUSAGE_SELF, &usage)
           ├─ フィールドコピー
           └─ ru_maxrss単位正規化

uv_getrusage_thread(rusage)
    ├─ [macOS] thread_info(THREAD_BASIC_INFO)
    │       ├─ mach_thread_self()
    │       ├─ memset(rusage, 0)
    │       ├─ utime/stime設定
    │       └─ mach_port_deallocate()
    ├─ [Solaris] uv__getrusage(RUSAGE_LWP, rusage)
    ├─ [Linux] uv__getrusage(RUSAGE_THREAD, rusage)
    └─ [Other] return UV_ENOTSUP
```

### データフロー図

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

rusage (uv_rusage_t*) --> uv_getrusage()             --> rusage->ru_utime
                          |                               rusage->ru_stime
                          +-- getrusage(RUSAGE_SELF)      rusage->ru_maxrss
                          +-- 単位正規化                   rusage->ru_minflt ...
                                                          戻り値: 0 or error

rusage (uv_rusage_t*) --> uv_getrusage_thread()      --> rusage->ru_utime
                          |                               rusage->ru_stime
                          +-- thread_info / getrusage     (その他フィールド)
                                                          戻り値: 0 or error
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_rusage_t構造体定義、API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix系uv_getrusage()/uv_getrusage_thread()/uv__getrusage()実装 |
| util.c | `src/win/util.c` | ソース | Windows版uv_getrusage()/uv_getrusage_thread()実装 |
