Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11255] ファイルの概要

このコミットは、Go言語のsyscallパッケージにおけるPlan 9オペレーティングシステム向けのビルド問題を修正するものです。具体的には、syscall_plan9.goファイルにTimespec構造体の定義を追加することで、システムコールが正しく機能するようにしています。

コミット

  • コミットハッシュ: e3e93b0f4398e57aae02a9eb05b1226731fc05e1
  • 作者: Mikio Hara mikioh.mikioh@gmail.com
  • 日付: 2012年1月19日 (木) 14:52:28 +0900
  • コミットメッセージ: syscall: fix plan9 build

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/e3e93b0f4398e57aae02a9eb05b1226731fc05e1

元コミット内容

syscall: fix plan9 build

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5532097

変更の背景

このコミットの主な背景は、Go言語のsyscallパッケージがPlan 9オペレーティングシステム上で正しくビルドできない、または実行時に必要なシステムコールインターフェースが不足しているという問題です。syscallパッケージは、Goプログラムが基盤となるオペレーティングシステムの機能(ファイル操作、プロセス管理、ネットワーク通信など)に直接アクセスするための低レベルなインターフェースを提供します。

Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、そのシステムコールインターフェースはUNIX系システムとは異なる場合があります。Go言語はクロスプラットフォーム対応を目指しており、各OS固有のシステムコールを適切にラップする必要があります。このコミット以前は、Plan 9環境で特定の時間関連のシステムコールを扱う際に、必要なTimespec構造体がsyscall_plan9.goに定義されていなかったため、コンパイルエラーや実行時エラーが発生していたと考えられます。

この修正は、Go言語がPlan 9環境でも安定して動作するための互換性向上の一環として行われました。

前提知識の解説

1. Go言語の syscall パッケージ

Go言語の標準ライブラリに含まれるsyscallパッケージは、オペレーティングシステムが提供する低レベルなシステムコールに直接アクセスするための機能を提供します。これにより、Goプログラムはファイルシステム、プロセス、ネットワーク、メモリ管理など、OSカーネルの機能を直接利用できます。このパッケージはOSごとに異なる実装を持ち、各OSのシステムコールインターフェースに合わせて調整されています。例えば、UNIX系OSではPOSIX標準に準拠したシステムコールが、WindowsではWin32 APIが利用されます。

2. Plan 9 オペレーティングシステム

Plan 9 from Bell Labsは、UNIXの後継としてベル研究所で開発された分散オペレーティングシステムです。UNIXの哲学をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルとして表現し、それらをファイルシステムを通じてアクセスするという特徴を持っています。そのシステムコールインターフェースはUNIXとは異なる部分が多く、Go言語のようなクロスプラットフォーム言語がPlan 9をサポートするためには、専用のラッパーや定義が必要となります。

3. Timespec 構造体

Timespecは、多くのUNIX系システムやPOSIX標準において、秒とナノ秒の精度で時間を表現するために使用される構造体です。通常、以下のような形式で定義されます。

struct timespec {
    time_t tv_sec;  // 秒
    long   tv_nsec; // ナノ秒 (0から999,999,999まで)
};

この構造体は、ファイルのタイムスタンプ(アクセス時刻、変更時刻など)や、高精度なタイマー、スリープ関数など、時間に関連する様々なシステムコールで使用されます。Go言語のsyscallパッケージでは、OSネイティブのtimespec構造体に対応するGoの型を定義し、Goプログラムからこれらのシステムコールを呼び出せるようにする必要があります。

4. Timeval 構造体

Timevalもまた、秒とマイクロ秒の精度で時間を表現するために使用される構造体です。

struct timeval {
    time_t tv_sec;  // 秒
    suseconds_t tv_usec; // マイクロ秒 (0から999,999まで)
};

TimevalTimespecよりも古い時代から使われており、主にselect()gettimeofday()といったシステムコールで利用されます。このコミットではTimevalの定義は既に存在しており、Timespecが追加されたことが示唆されています。

技術的詳細

このコミットの技術的な核心は、Go言語のsyscallパッケージがPlan 9環境で時間関連のシステムコールを正しく扱うために、Timespec構造体のGo言語での定義が不足していた点にあります。

Go言語のsyscallパッケージは、各オペレーティングシステム固有のシステムコールをGoの関数としてラップし、Goプログラムから透過的に利用できるようにします。この際、OSネイティブのC言語の構造体に対応するGoの構造体を定義する必要があります。

Plan 9では、特定のシステムコール(例えば、ファイルのタイムスタンプを設定するutimensatのような関数や、高精度なスリープ関数など)がTimespec構造体を引数として要求する場合があります。syscall_plan9.goファイルは、Plan 9固有のシステムコールインターフェースを定義する場所です。このファイルにTimespec構造体のGo言語での定義がなかったため、Timespecを必要とするGoのコードがPlan 9上でコンパイルされる際に、未定義の型としてエラーが発生していました。

追加されたTimespec構造体は、Sec(秒)とNsec(ナノ秒)という2つのint32型のフィールドを持ちます。これは、Plan 9のネイティブなtimespec構造体(もし存在すれば)や、一般的なPOSIXのtimespec構造体と互換性を持たせるためのものです。int32が選択されているのは、当時のPlan 9のシステムコールインターフェースやGoの内部表現の都合によるものと考えられます。

この定義を追加することで、GoコンパイラはTimespec型を認識し、Plan 9固有のシステムコールを呼び出す際に必要な引数の型チェックやメモリレイアウトを正しく処理できるようになります。結果として、Plan 9上でのGoプログラムのビルドが成功し、時間関連のシステムコールが期待通りに動作するようになります。

コアとなるコードの変更箇所

変更はsrc/pkg/syscall/syscall_plan9.goファイルに対して行われました。

diff --git a/src/pkg/syscall/syscall_plan9.go b/src/pkg/syscall/syscall_plan9.go
index cd348f890d..0bbb7ece99 100644
--- a/src/pkg/syscall/syscall_plan9.go
+++ b/src/pkg/syscall/syscall_plan9.go
@@ -268,6 +268,11 @@ func Fchdir(fd int) (err error) {
  	return Chdir(path)
  }

+type Timespec struct {
+\tSec  int32
+\tNsec int32
+}
+
 type Timeval struct {
  	Sec  int32
  	Usec int32

コアとなるコードの解説

このコミットのコアとなる変更は、src/pkg/syscall/syscall_plan9.goファイルに以下のTimespec構造体を追加したことです。

type Timespec struct {
	Sec  int32
	Nsec int32
}

このコードは、Go言語におけるTimespec構造体の定義です。

  • type Timespec struct { ... }: Timespecという名前の新しい構造体型を定義しています。
  • Sec int32: Secという名前のフィールドを定義しており、これは秒を表すために使用されます。型はint32です。
  • Nsec int32: Nsecという名前のフィールドを定義しており、これはナノ秒を表すために使用されます。型はint32です。

この定義が追加されることで、syscallパッケージ内の他の関数や、syscallパッケージを利用するGoのコードが、Plan 9環境でTimespec型の値を生成したり、システムコールに渡したり、システムコールから受け取ったりすることが可能になります。

例えば、もしPlan 9にutimensatのようなシステムコールがあり、それがTimespec構造体を引数として取る場合、この定義がなければGoのコードはコンパイルエラーになります。この定義が追加されたことで、GoのsyscallパッケージはPlan 9のネイティブな時間表現とGoの型システムとの間の橋渡しができるようになり、Plan 9上でのGoプログラムの互換性と機能性が向上しました。

この変更は、既存のTimeval構造体の定義の直前に追加されており、時間関連の構造体がまとまって配置されるように配慮されています。

関連リンク

参考にした情報源リンク