# 帳票設計書 4-イベントループアイドル時間

## 概要

本ドキュメントは、libuvライブラリにおける `uv_metrics_idle_time()` API関数の帳票設計書である。イベントループプロバイダ（epoll/kqueue等）のアイドル時間をナノ秒単位で返却する機能について定義する。

### 本帳票の処理概要

本帳票は、イベントループがI/Oポーリングプロバイダ内でアイドル状態（イベント待ち）であった累計時間をナノ秒単位で返却する機能を提供する。

**業務上の目的・背景**：イベントループの効率性を定量的に評価するために、ループがイベント待ちで消費した時間を計測する。アイドル時間が短い場合はCPUバウンドな処理が多いことを示し、長い場合はI/Oバウンドであることを示す。この指標はアプリケーションのパフォーマンスプロファイリングにおいて重要である。

**帳票の利用シーン**：イベントループの効率性測定、CPUバウンド処理とI/Oバウンド処理の比率分析、パフォーマンスモニタリングダッシュボードへのメトリクス提供。

**主要な出力内容**：
1. アイドル時間（uint64_t）：ナノ秒単位のI/Oプロバイダアイドル累計時間

**帳票の出力タイミング**：`uv_metrics_idle_time(loop)` 呼び出し時に即座に返却される。UV_METRICS_IDLE_TIMEオプションが有効な場合のみ正確な値が返される。

**帳票の利用者**：パフォーマンスエンジニア、アプリケーション開発者、運用監視チーム。

## 帳票種別

メトリクスレポート（単一値返却）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | N/A（C API呼び出し） | N/A | `uv_metrics_idle_time(loop)` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | uint64_t型戻り値 |
| 出力方法 | 関数戻り値 |
| 単位 | ナノ秒 |

## 帳票レイアウト

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | サイズ |
|----|-------|------|-------------|---------|------|
| 1 | idle_time | I/Oプロバイダアイドル累計時間 | loop_metrics->provider_idle_time + (現在時刻 - entry_time) | uint64_t（ナノ秒） | 8バイト |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| イベントループ | アイドル時間を取得するイベントループ | Yes |
| UV_METRICS_IDLE_TIME | ループ設定でこのオプションが有効であること | Yes（有効でないと常に0） |

### ソート順

N/A（単一値返却）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名（データ構造） | 用途 | 結合条件 |
|-----------|------|---------|
| uv__loop_metrics_t | アイドル時間データの格納 | uv__get_loop_metrics()マクロ経由 |

### テーブル別参照項目詳細

#### uv__loop_metrics_t

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| provider_idle_time | 累計アイドル時間 | mutex lockで排他アクセス | ナノ秒単位 |
| provider_entry_time | プロバイダ進入時刻 | mutex lockで排他アクセス | 0の場合はプロバイダ外 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 基本アイドル時間 | provider_idle_time（ロック取得して読み取り） | N/A | 累計値 |
| 現在進行中のアイドル | entry_time > 0 の場合: idle_time += uv_hrtime() - entry_time | N/A | プロバイダ内にいる場合の補正 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_metrics_idle_time呼び出し] --> B[uv__get_loop_metricsでloop_metrics取得]
    B --> C[mutex lock取得]
    C --> D[provider_idle_timeを読み取り]
    D --> E[provider_entry_timeを読み取り]
    E --> F[mutex lock解放]
    F --> G{entry_time > 0?}
    G -->|Yes| H[idle_time += uv_hrtime - entry_time]
    G -->|No| I[idle_timeをそのまま返却]
    H --> I
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| N/A | エラーは発生しない | N/A | UV_METRICS_IDLE_TIME未設定時は0が返される |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件（固定） |
| 目標出力時間 | マイクロ秒オーダー（mutex lock/unlock + uv_hrtime()呼び出し） |
| 同時出力数上限 | N/A |

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

特になし。アイドル時間の値はサイドチャネル攻撃の観点ではリスクが低い。

## 備考

- UV_METRICS_IDLE_TIMEオプションは `uv_loop_configure(loop, UV_METRICS_IDLE_TIME)` で有効化する
- スレッドセーフ：mutex lockにより排他制御されている
- provider_entry_timeが0でない場合、現在I/Oプロバイダ内にいることを示し、現在時刻までの差分を加算する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv-common.h | `src/uv-common.h` | uv__loop_metrics_t構造体（399-404行目）のprovider_entry_time, provider_idle_time, lockメンバ |
| 1-2 | uv.h | `include/uv.h` | UV_METRICS_IDLE_TIMEオプション定義（263行目） |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv-common.c | `src/uv-common.c` | uv_metrics_idle_time()（1042-1056行目）の実装全体 |

**主要処理フロー**:
1. **1047行目**: `uv__get_loop_metrics(loop)` でloop_metricsポインタ取得
2. **1048行目**: `uv_mutex_lock(&loop_metrics->lock)` でロック取得
3. **1049-1050行目**: idle_timeとentry_timeを読み取り
4. **1051行目**: `uv_mutex_unlock(&loop_metrics->lock)` でロック解放
5. **1053-1054行目**: entry_time > 0なら現在のアイドル時間を加算
6. **1055行目**: idle_timeを返却

#### Step 3: アイドル時間の更新メカニズムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uv-common.c | `src/uv-common.c` | uv__metrics_update_idle_time()（991-1015行目）：プロバイダから戻った時にアイドル時間を更新 |
| 3-2 | uv-common.c | `src/uv-common.c` | uv__metrics_set_provider_entry_time()（1018-1030行目）：プロバイダに入る時にentry_timeを設定 |

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

```
uv_metrics_idle_time(loop)                        [src/uv-common.c:1042]
    |
    +-- uv__get_loop_metrics(loop)                [src/uv-common.h:369]
    +-- uv_mutex_lock(&loop_metrics->lock)        [スレッド同期]
    +-- uv_mutex_unlock(&loop_metrics->lock)      [スレッド同期]
    +-- uv_hrtime()                               [src/unix/core.c:154]  ※entry_time > 0の場合
```

### データフロー図

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

uv__loop_metrics_t            uv_metrics_idle_time()         uint64_t
  .provider_idle_time ---+    1042-1056行目                  (ナノ秒)
  .provider_entry_time --+--> ロック取得 -> 読取 -> 計算 --> idle_time返却
  .lock                       ロック解放
                              entry_time > 0なら
uv_hrtime() ------------------> 現在時刻との差分を加算
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言、UV_METRICS_IDLE_TIMEオプション定義 |
| uv-common.h | `src/uv-common.h` | 内部ヘッダ | uv__loop_metrics_t構造体定義 |
| uv-common.c | `src/uv-common.c` | ソース | uv_metrics_idle_time()、uv__metrics_update_idle_time()、uv__metrics_set_provider_entry_time()実装 |
