# 帳票設計書 14-top - CPU使用率上位プロセスレポート

## 概要

本ドキュメントは、FreeBSD の `top` コマンドが出力するCPU使用率上位プロセスレポートの設計仕様を記述する。

### 本帳票の処理概要

top は、CPU使用率の高いプロセスの情報をリアルタイムで表示・更新するレポートを出力するユーティリティである。システム全体のCPU、メモリ、スワップの使用状況と、プロセスの詳細情報を定期的に更新しながら表示する。

**業務上の目的・背景**：システムのリアルタイムパフォーマンス監視に使用される。CPU負荷の高いプロセスの特定、メモリ使用状況の把握、システムリソースのボトルネック分析などの課題を解決する。

**帳票の利用シーン**：システム負荷調査、パフォーマンス問題のトリアージ、リソース消費の多いプロセスの特定、システム稼働状況のリアルタイム監視などの場面で利用される。

**主要な出力内容**：
1. システムサマリー（最終更新時刻、稼働時間、プロセス数）
2. CPU使用率（user/nice/system/interrupt/idle）
3. メモリ使用状況（Active/Inact/Wired/Buf/Free）
4. スワップ使用状況
5. プロセス一覧（PID、ユーザー、優先度、サイズ、CPU使用率、コマンド名等）

**帳票の出力タイミング**：管理者がコマンドラインから `top` コマンドを実行した際にリアルタイムで定期更新表示される。バッチモード（-b）では1回出力して終了も可能。

**帳票の利用者**：システム管理者、運用監視担当者、開発者

## 帳票種別

一覧表（リアルタイム更新型プロセス一覧）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | コマンドラインインターフェース（curses） | N/A | `top` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（端末画面/標準出力） |
| 用紙サイズ | N/A（端末サイズに適応） |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | 端末画面（curses）またはバッチ出力 |
| 文字コード | ロケール依存 |

## 帳票レイアウト

### レイアウト概要

ヘッダー部（システムサマリー）と明細部（プロセス一覧）で構成される。

```
┌─────────────────────────────────────────────────────────────┐
│ last pid: xxxxx;  load averages: x.xx, x.xx, x.xx          │
│ xxx processes: x running, x sleeping, ...                    │
│ CPU: x.x% user, x.x% nice, x.x% system, x.x% idle         │
│ Mem: xxxM Active, xxxM Inact, xxxM Wired, xxxM Buf, xxxM Free│
│ Swap: xxxM Total, xxxM Used, xxxM Free                       │
├─────────────────────────────────────────────────────────────┤
│ PID USERNAME  THR PRI NICE  SIZE   RES STATE    C TIME  WCPU │
│ (プロセス一覧が繰り返し表示)                                  │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 最終PID | 最後に割り当てられたPID | sysctl | "last pid: %d" |
| 2 | ロードアベレージ | 1/5/15分間のロードアベレージ | getloadavg() | "load averages: %.2f, %.2f, %.2f" |
| 3 | プロセス数 | 状態別プロセス数 | /dev/kmem, kvm | "xxx processes: ..." |
| 4 | CPU使用率 | user/nice/system/interrupt/idle | kern.cp_time sysctl | パーセント表示 |
| 5 | メモリ使用状況 | Active/Inact/Wired/Buf/Free | vm.stats.vm sysctl | メガバイト表示 |
| 6 | スワップ使用状況 | Total/Used/Free | kvm_getswapinfo() | メガバイト表示 |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | PID | プロセスID | ki_pid | 整数 | 可変 |
| 2 | USERNAME | ユーザー名 | ki_uid | 文字列 | 可変 |
| 3 | THR | スレッド数 | ki_numthreads | 整数 | 可変 |
| 4 | PRI | 優先度 | ki_pri.pri_level | 整数 | 可変 |
| 5 | NICE | nice値 | ki_nice | 整数 | 可変 |
| 6 | SIZE | 仮想メモリサイズ | ki_size | human-readable | 可変 |
| 7 | RES | 常駐メモリサイズ | ki_rssize | human-readable | 可変 |
| 8 | STATE | プロセス状態 | ki_stat | 文字列 | 可変 |
| 9 | C | CPU番号 | ki_lastcpu | 整数 | 可変 |
| 10 | TIME | CPU累積時間 | ki_runtime | H:MM:SS | 可変 |
| 11 | WCPU/CPU | CPU使用率 | ki_pctcpu | パーセント | 可変 |
| 12 | COMMAND | コマンド名/コマンドライン | ki_comm / ki_args | 文字列 | 残り幅 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 表示プロセス数 | 画面に表示するプロセス数の上限 | No（端末サイズに依存） |
| ユーザーフィルタ | 特定ユーザーのプロセスのみ表示（-U） | No |
| アイドルプロセス除外 | アイドルプロセスを非表示（-I） | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | CPU使用率 | 降順（デフォルト） |
| (選択可能) | メモリサイズ、PID等 | 対話的に変更可能 |

### 改ページ条件

改ページなし（端末画面内でスクロール、定期更新）

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| /dev/kmem（kvm） | プロセス情報取得 | kvm_getprocs() |
| sysctl (kern.cp_time) | CPU使用率 | sysctlbyname |
| sysctl (vm.stats.*) | メモリ統計 | sysctlbyname |
| kvm_getswapinfo | スワップ情報 | kvm経由 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| CPU使用率(%) | (cp_time差分) / 合計差分 * 100 | 小数点以下1桁 | 前回サンプリングとの差分 |
| メモリ使用量 | ページ数 * ページサイズ / 1024/1024 | メガバイト | vm.stats.vmから取得 |
| WCPU | 重み付きCPU使用率 | パーセント | 指数減衰による重み付け |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[topコマンド実行] --> B[オプション解析・初期化]
    B --> C[kvm_open / sysctl初期化]
    C --> D[プロセス情報取得]
    D --> E[CPU/メモリ統計取得]
    E --> F[プロセスソート]
    F --> G[画面描画]
    G --> H{バッチモード?}
    H -->|Yes| I[終了]
    H -->|No| J[sleep(interval)]
    J --> D
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| kvm_open失敗 | カーネルメモリアクセス不可 | kvm_geterr()のメッセージ | エラー終了 |
| sysctl失敗 | カーネルパラメータ取得不可 | "sysctl failed" | エラー終了 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | プロセス数（数十〜数千） |
| 目標出力時間 | 更新間隔内（デフォルト2秒） |
| 同時出力数上限 | 端末あたり1インスタンス |

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

- /dev/kmem へのアクセスにはkmem グループ権限またはroot権限が必要
- 全プロセスの情報が表示されるため、マルチユーザー環境ではアクセス制御が重要
- -s オプションでセキュアモード（プロセスkill等の対話操作を禁止）

## 備考

- machine.c にFreeBSD固有のプロセス情報取得ロジックが実装されている
- top.c はポータブルなフレームワーク部分を担当
- libkvm を使用してカーネルメモリからプロセス情報を取得
- 対話モードでは 'q' で終了、'o' でソート順変更等が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | machine.h | `usr.bin/top/machine.h` | topプログラム内部のデータ構造定義 |
| 1-2 | machine.c | `usr.bin/top/machine.c` | struct kinfo_proc の使用方法、CPU/メモリ統計の取得構造 |

**読解のコツ**: top はポータブルな設計のため、OS固有部分は machine.c に集約されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | top.c | `usr.bin/top/top.c` | main()：オプション解析、メインループ |

**主要処理フロー**:
1. オプション解析（getopt）
2. machine_init()でOS固有初期化
3. メインループ：get_system_info() / get_process_info() / display_update()

#### Step 3: OS固有データ取得層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | machine.c | `usr.bin/top/machine.c` | machine_init()、get_system_info()、get_process_info()、format_next_process() |

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

```
main() [top.c]
    |
    +-- machine_init() [machine.c]
    |       +-- kvm_open()
    |       +-- sysctl初期化
    |
    +-- メインループ
            |
            +-- get_system_info() [machine.c]
            |       +-- sysctlbyname("kern.cp_time")
            |       +-- sysctlbyname("vm.stats.*")
            |       +-- kvm_getswapinfo()
            |
            +-- get_process_info() [machine.c]
            |       +-- kvm_getprocs()
            |       +-- プロセスソート
            |
            +-- display_update() [display.c]
                    +-- i_header() / u_header()
                    +-- i_process() / u_process()
```

### データフロー図

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

/dev/kmem ───────────> kvm_getprocs() ──────────> 端末画面
(プロセス情報)          get_process_info()          (curses)
sysctl ──────────────> get_system_info()
(CPU/メモリ統計)        format_next_process()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| top.c | `usr.bin/top/top.c` | ソース | メインプログラム、メインループ |
| machine.c | `usr.bin/top/machine.c` | ソース | FreeBSD固有のデータ取得・フォーマット |
| display.c | `usr.bin/top/display.c` | ソース | 画面表示ロジック |
| machine.h | `usr.bin/top/machine.h` | ヘッダ | machine層のインターフェース定義 |
| top.h | `usr.bin/top/top.h` | ヘッダ | 共通定義 |
| Makefile | `usr.bin/top/Makefile` | ビルド | ビルド設定（libkvm/libm/libncursesw依存） |
