# 機能設計書 170-高精度時刻取得

## 概要

本ドキュメントは、libuv の `uv_hrtime()` APIによるナノ秒精度の高精度タイムスタンプ取得機能について記述する。

### 本機能の処理概要

本機能は、ナノ秒精度のモノトニック（単調増加）タイムスタンプを取得するためのクロスプラットフォームAPIを提供する。プロセス起動からの経過時間の計測、パフォーマンス測定、タイマー精度の管理などに使用される。

**業務上の目的・背景**：高精度な時間計測はパフォーマンスプロファイリング、ベンチマーク、精密なタイミング制御に不可欠である。各OSで高精度タイマーのAPIが異なる（macOS: mach_continuous_time、Linux: clock_gettime(CLOCK_MONOTONIC)、Windows: QueryPerformanceCounter）ため、これらの差異を吸収するクロスプラットフォームAPIが必要となる。

**機能の利用シーン**：パフォーマンス計測、ベンチマーキング、イベントループ内部の時間管理、タイムアウト計算の基盤、相対時間の計測（2つのuv_hrtime()呼び出しの差分）に利用される。

**主要な処理内容**：
1. プラットフォーム固有の高精度時計API（`uv__hrtime()`内部関数）を呼び出す
2. ナノ秒単位のuint64_t値を返却する
3. モノトニック（単調増加）であることを保証する

**関連システム・外部連携**：macOS `mach_continuous_time()` + `mach_timebase_info()`、Linux/POSIX `clock_gettime(CLOCK_MONOTONIC)`、Windows `QueryPerformanceCounter()`を使用する。

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_hrtime()によるナノ秒精度タイムスタンプ取得のAPI定義 |

## 機能種別

システム情報取得

## 入力仕様

### 入力パラメータ

本関数はパラメータを取らない。

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | void | - | 引数なし | - |

### 入力データソース

OSの高精度タイマー

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | uint64_t | ナノ秒単位のタイムスタンプ |

### 出力先

呼び出し元に直接返却

## 処理フロー

### 処理シーケンス

```
uv_hrtime():
1. uv__hrtime(UV_CLOCK_PRECISE)を呼び出す
   └─ プラットフォーム固有の内部関数

[macOS (darwin.c)]:
1. uv_once()でタイムベース情報を初期化（初回のみ）
2. mach_continuous_time()でタイマー値を取得
3. timebase.numer / timebase.denom で ナノ秒に変換

[Linux/POSIX (posix-hrtime.c)]:
1. clock_gettime(CLOCK_MONOTONIC, &t)を呼び出す
   └─ 失敗した場合abort()
2. t.tv_sec * 1e9 + t.tv_nsecでナノ秒に変換
```

### フローチャート

```mermaid
flowchart TD
    A[uv_hrtime呼び出し] --> B[uv__hrtime UV_CLOCK_PRECISE]
    B --> C{プラットフォーム}
    C -->|macOS| D[uv_once でタイムベース初期化]
    D --> E[mach_continuous_time]
    E --> F[numer / denom でナノ秒変換]
    C -->|Linux/POSIX| G[clock_gettime CLOCK_MONOTONIC]
    G --> H{成功?}
    H -->|No| I[abort]
    H -->|Yes| J[tv_sec * 1e9 + tv_nsec]
    F --> K[uint64_t返却]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | モノトニック保証 | 返却値は単調増加であり、システム時刻の変更に影響されない | 常時 |
| BR-02 | ナノ秒精度 | 返却値はナノ秒単位のuint64_tである | 常時 |
| BR-03 | 精密モード | UV_CLOCK_PRECISEモードで呼び出される（最高精度） | 常時 |
| BR-04 | タイムベース初回初期化 | macOSでは初回呼び出し時にmach_timebase_infoを初期化（uv_once使用） | macOS |

### 計算ロジック

macOS: `mach_continuous_time() * timebase.numer / timebase.denom`
Linux/POSIX: `t.tv_sec * (uint64_t)1e9 + t.tv_nsec`

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

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (abort) | 致命的エラー | clock_gettime()が失敗（POSIX） | 発生しないことが前提 |
| (abort) | 致命的エラー | mach_timebase_info()がKERN_SUCCESS以外（macOS） | 発生しないことが前提 |

### リトライ仕様

エラーはabort()で処理されるため、リトライの概念はない。

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

該当なし

## パフォーマンス要件

非常に高速に実行される必要がある。パフォーマンス計測自体に使用されるため、オーバーヘッドは最小限であること。通常はナノ秒オーダーで完了する。

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

- タイムスタンプの絶対値には特にセキュリティ上の意味はない
- 相対時間の計測に使用するため、基準時点は不定

## 備考

- uint64_tの最大値（約18.4 * 10^18ナノ秒 = 約584年）を超えることは実用上ない
- uv__hrtime()はプラットフォーム固有の内部関数であり、複数の実装ファイルに分かれている
- macOSではmach_continuous_time()を使用（スリープ中もカウント継続）
- Linux/POSIXではclock_gettime(CLOCK_MONOTONIC)を使用
- AIX、OS/390、SunOSなどにも個別の実装がある
- `include/uv.h` L1837 で定義

---

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

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

### 推奨読解順序

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

本機能は固有のデータ構造を使用しない。uint64_tのスカラー値を返す。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L1837: uv_hrtime()のAPI宣言（uint64_t返却） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | L154-156: uv_hrtime()の実装（uv__hrtime(UV_CLOCK_PRECISE)への委譲） |

**主要処理フロー**:
1. **154行目**: 関数定義
2. **155行目**: `uv__hrtime(UV_CLOCK_PRECISE)` を呼び出してその結果を返す

**読解のコツ**: `UV_CLOCK_PRECISE`はenum値で、最高精度の時計を使用することを示す。対して`UV_CLOCK_FAST`はより低精度だが高速な読み取りが可能（一部プラットフォーム）。

#### Step 3: プラットフォーム固有実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | darwin.c | `src/unix/darwin.c` | L54-63: macOS実装（mach_continuous_time） |
| 3-2 | posix-hrtime.c | `src/unix/posix-hrtime.c` | L29-36: POSIX汎用実装（clock_gettime） |

**macOS実装 (darwin.c)**:
- **54-57行目**: `uv__hrtime_init_once()` でmach_timebase_infoを初期化
- **60行目**: 関数定義
- **61行目**: `uv_once()` でタイムベース情報を一度だけ初期化
- **62行目**: `mach_continuous_time() * timebase.numer / timebase.denom` でナノ秒計算

**POSIX実装 (posix-hrtime.c)**:
- **29行目**: 関数定義
- **32行目**: `clock_gettime(CLOCK_MONOTONIC, &t)` 呼び出し
- **33行目**: 失敗時abort()
- **35行目**: `t.tv_sec * (uint64_t) 1e9 + t.tv_nsec` でナノ秒計算

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

```
uv_hrtime() [src/unix/core.c:154]
    |
    +-- uv__hrtime(UV_CLOCK_PRECISE)
           |
           +-- [macOS] mach_continuous_time() [src/unix/darwin.c:62]
           |            * timebase.numer / timebase.denom
           |
           +-- [Linux/POSIX] clock_gettime(CLOCK_MONOTONIC) [src/unix/posix-hrtime.c:32]
           |                  tv_sec * 1e9 + tv_nsec
           |
           +-- [AIX] read_wall_time() [src/unix/aix-common.c]
           +-- [SunOS] gethrtime() [src/unix/sunos.c]
           +-- [OS/390] __stck() [src/unix/os390.c]
```

### データフロー図

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

(なし)         ───> OS固有の高精度タイマーAPI    ───> uint64_t (ナノ秒)
                    ナノ秒への変換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L1837） |
| core.c | `src/unix/core.c` | ソース | 共通エントリーポイント（L154-156） |
| darwin.c | `src/unix/darwin.c` | ソース | macOS実装（L54-63） |
| posix-hrtime.c | `src/unix/posix-hrtime.c` | ソース | POSIX汎用実装（L29-36） |
| linux.c | `src/unix/linux.c` | ソース | Linux実装 |
| aix-common.c | `src/unix/aix-common.c` | ソース | AIX実装 |
| sunos.c | `src/unix/sunos.c` | ソース | SunOS実装 |
| os390.c | `src/unix/os390.c` | ソース | OS/390実装 |
| internal.h | `src/unix/internal.h` | ヘッダー | uv_clocktype_t定義、uv__hrtime宣言 |
