[インデックス 10367] ファイルの概要
このコミットは、Go言語のtimeパッケージから使用されていないsysSleep
関数を削除するリファクタリングです。Russ Coxによって2011年11月13日に行われたこの変更は、Go 1.0のリリースに向けた準備段階でのコードクリーンアップの一環として実施されました。
コミット
- コミットハッシュ: b126902e84891737e7f94a547b4273dc37706065
- 作成者: Russ Cox rsc@golang.org
- 日付: 2011年11月13日 22:42:57 -0500
- コミットメッセージ: "time: remove unused sysSleep"
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/6ab6c49fce6968f200ad5381cb9348e159e51099
元コミット内容
time: remove unused sysSleep
R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/5369094
変更されたファイル:
src/pkg/time/sys_plan9.go
: 8行削除src/pkg/time/sys_unix.go
: 8行削除src/pkg/time/sys_windows.go
: 13行削除- 合計: 3ファイル、29行削除
変更の背景
このコミットは、Go 1.0のリリースに向けた準備段階で実施されたコードクリーンアップの一環です。2011年11月の時点では、Go言語はまだ1.0リリース前の開発段階にあり、同年11月9日にRuss Coxが行った重要な変更(runtime: add timer support)によってタイマー機能の実装が根本的に変更されました。
この変更により、timeパッケージのSleep、NewTicker、NewTimer機能が統一されたメカニズムの下で動作するようになり、従来のsysSleep関数が不要になりました。これは、Go言語がより効率的でスケーラブルなランタイムシステムに移行する過程で行われた重要な改善の一つです。
前提知識の解説
Go言語の初期のタイマー実装
Go言語の初期版(1.0リリース前)では、時間関連の機能は複数の異なるメカニズムで実装されていました:
- sysSleep関数: 各プラットフォーム(Unix、Windows、Plan 9)ごとに実装されたシステムコールベースのスリープ機能
- タイマーヒープ: timeパッケージ内で管理されるタイマーのスケジューリング機能
- ゴルーチン単位のブロッキング: 個々のゴルーチンがOSスレッドをブロックする方式
プラットフォーム固有の実装
Go言語は複数のオペレーティングシステムをサポートしており、各プラットフォームで異なるシステムコールを使用する必要がありました:
- Unix系システム:
syscall.Sleep()
を使用 - Windows:
syscall.Sleep()
を使用(実装が異なる) - Plan 9: Bell Labsで開発されたオペレーティングシステム用の実装
ランタイム統合の必要性
2011年11月9日の重要な変更により、タイマー機能がランタイムレベルで統一されました。これにより以下の利点が得られました:
- 効率性の向上: OSスレッドのブロックを避けることで、ゴルーチンの軽量性を維持
- 統一性: Sleep、Timer、Tickerが同じメカニズムを使用
- スケーラビリティ: 大量のゴルーチンが同時にスリープしても性能が劣化しない
技術的詳細
削除された関数の解析
各プラットフォームのsysSleep
関数は以下の共通パターンを持っていました:
func sysSleep(t int64) error {
// プラットフォーム固有のシステムコール
errno := syscall.Sleep(t)
// エラーハンドリング
if errno != 0 && errno != syscall.EINTR {
return os.NewSyscallError("sleep", errno)
}
return nil
}
エラーハンドリングの特徴
- EINTR (Interrupted system call): シグナルによって中断されたシステムコールは正常として扱う
- NewSyscallError: Goの標準的なシステムコールエラーラッピング
- 戻り値: errorインターフェースを使用した統一的なエラーハンドリング
プラットフォーム間の差異
- Plan 9: 最もシンプルな実装、エラーハンドリングが若干異なる
- Unix: EINTR(シグナル割り込み)を考慮した実装
- Windows: Unixと同様の実装パターンだが、内部的にはWin32 APIを使用
コアとなるコードの変更箇所
src/pkg/time/sys_plan9.go
-func sysSleep(t int64) error {
- err := syscall.Sleep(t)
- if err != nil {
- return os.NewSyscallError("sleep", err)
- }
- return nil
-}
src/pkg/time/sys_unix.go
-func sysSleep(t int64) error {
- errno := syscall.Sleep(t)
- if errno != 0 && errno != syscall.EINTR {
- return os.NewSyscallError("sleep", errno)
- }
- return nil
-}
src/pkg/time/sys_windows.go
-import (
- "os"
- "syscall"
-)
-
-func sysSleep(t int64) error {
- errno := syscall.Sleep(t)
- if errno != 0 && errno != syscall.EINTR {
- return os.NewSyscallError("sleep", errno)
- }
- return nil
-}
コアとなるコードの解説
関数シグネチャの分析
func sysSleep(t int64) error
- パラメータ:
t int64
- スリープ時間をナノ秒単位で指定 - 戻り値:
error
- エラーまたはnil - 可視性: 小文字で始まるため、パッケージ内でのみ使用可能
エラーハンドリングの詳細
各プラットフォームでエラーハンドリングのアプローチが微妙に異なります:
- Plan 9:
err != nil
でシンプルに判定 - Unix/Windows:
errno != 0 && errno != syscall.EINTR
でより詳細な制御
この違いは、各オペレーティングシステムのシステムコールの仕様とシグナルハンドリングの違いを反映しています。
削除の影響と代替手段
sysSleep
関数の削除により、timeパッケージは以下の新しいアーキテクチャに移行しました:
- ランタイム統合: タイマー機能がランタイムレベルで管理される
- 統一API:
time.Sleep()
が唯一のスリープインターフェース - 効率化: ゴルーチンレベルでのスケジューリング
インポートの最適化
Windows版では、sysSleep
関数の削除により、以下のインポートも不要になりました:
import (
"os"
"syscall"
)
これにより、コードの依存関係が簡素化され、timeパッケージの初期化時間も短縮されました。