[インデックス 12877] ファイルの概要
このコミットは、Go言語のランタイムがOpenBSDオペレーティングシステム上でスレッド関連のシステムコール(threxit
とthrsleep
)を扱う方法を更新するものです。具体的には、OpenBSD 5.1カーネルのABI(Application Binary Interface)変更に対応するために、これらのシステムコールの呼び出し規約を調整しています。この変更は、古いカーネルとの後方互換性を維持しつつ、新しいカーネル環境での正しい動作を保証することを目的としています。
コミット
commit 8cea1bf1022272ee12fc03ef939a2ea1201d34d1
Author: Joel Sing <jsing@google.com>
Date: Wed Apr 11 22:02:08 2012 +1000
runtime: update openbsd thread related syscalls to match kernel
Update the threxit and thrsleep syscalls to match the ABI of the
OpenBSD 5.1 kernel. These changes are backwards compatible with
older kernels.
Fixes #3311.
R=golang-dev, rsc, devon.odell
CC=golang-dev
https://golang.org/cl/5777079
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8cea1bf1022272ee12fc03ef939a2ea1201d34d1
元コミット内容
GoランタイムにおけるOpenBSDのスレッド関連システムコールをカーネルに合わせるための更新。
OpenBSD 5.1カーネルのABIに合わせるため、threxit
とthrsleep
システムコールを更新。これらの変更は古いカーネルとも後方互換性がある。
Go Issue #3311を修正。
変更の背景
この変更の背景には、OpenBSDオペレーティングシステムのカーネルにおけるシステムコール(syscall)のABI(Application Binary Interface)の変更があります。特にOpenBSD 5.1カーネルでは、スレッドの終了(threxit
)とスレッドの待機(thrsleep
)に関連するシステムコールの呼び出し規約が変更されました。
Go言語のランタイムは、OSの低レベルな機能(スレッド管理、メモリ管理など)を直接利用するために、システムコールを頻繁に呼び出します。OSのABIが変更されると、Goランタイムが期待するシステムコールの引数の渡し方や戻り値の形式がOS側の実装と合わなくなり、プログラムが正しく動作しなくなる可能性があります。
このコミットは、GoランタイムがOpenBSD 5.1以降のカーネルでも正しくスレッドを管理できるように、これらのシステムコールの呼び出し規約をGoランタイム側で調整することを目的としています。同時に、古いOpenBSDカーネルとの後方互換性も維持することが重要な要件でした。これは、Goプログラムが異なるバージョンのOpenBSD上で動作することを保証するためです。
また、コミットメッセージに「Fixes #3311」とあることから、この変更はGoのIssueトラッカーで報告されていた特定のバグや問題(おそらくOpenBSD 5.1上でのGoプログラムのクラッシュや誤動作)を解決するために行われたことがわかります。
前提知識の解説
1. システムコール (System Call)
システムコールは、オペレーティングシステム(OS)のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。プログラムがファイルを開く、メモリを割り当てる、ネットワーク通信を行う、スレッドを作成・管理するといったOSの機能を利用する際には、直接ハードウェアにアクセスするのではなく、システムコールを介してカーネルに処理を依頼します。
システムコールは通常、特定の番号(システムコール番号)と引数によって識別され、OSによって定義されたABIに従って呼び出されます。
2. ABI (Application Binary Interface)
ABIは、コンパイルされたプログラム(バイナリ)が、OSやライブラリとどのようにやり取りするかを定義する低レベルなインターフェースです。具体的には、以下の要素を規定します。
- システムコールの呼び出し規約: システムコールを呼び出す際に、引数をどのレジスタに格納するか、スタックにどのように積むか、戻り値をどのレジスタで受け取るかなど。
- データ構造のメモリレイアウト: 構造体や共用体などのデータ型がメモリ上でどのように配置されるか。
- 関数呼び出し規約: 関数を呼び出す際の引数の渡し方、スタックフレームの管理、戻り値の受け取り方など。
- レジスタの使用規約: 関数呼び出し前後でどのレジスタが保存されるべきかなど。
ABIが変更されると、古いABIでコンパイルされたバイナリは新しいABIのOS上で正しく動作しない可能性があります。
3. OpenBSD
OpenBSDは、セキュリティを最優先に設計されたUNIX系オペレーティングシステムです。厳格なコードレビューとセキュリティ機能の実装で知られています。Go言語のランタイムは、様々なOSに対応するために、各OS固有のシステムコールやABIに対応するコードを含んでいます。
4. Goランタイム (Go Runtime)
Go言語のプログラムは、Goランタイムと呼ばれる実行環境上で動作します。Goランタイムは、ガベージコレクション、スケジューラ(ゴルーチンの管理)、メモリ管理、システムコールへの低レベルなインターフェースなど、Goプログラムの実行に必要な多くの機能を提供します。OS固有の機能にアクセスする際には、GoランタイムがそのOSのABIに合わせたシステムコールを呼び出します。
5. threxit
システムコール
threxit
は、スレッドを終了させるためのシステムコールです。通常、スレッドが自身の実行を終了する際に呼び出されます。OSによっては、スレッドの終了ステータスを親プロセスや他のスレッドに通知する機能も持ちます。
6. thrsleep
システムコール
thrsleep
は、スレッドを一時的にスリープ(待機)させるためのシステムコールです。特定の条件が満たされるまで、または指定された時間が経過するまでスレッドの実行を中断するために使用されます。これは、同期メカニズム(ミューテックス、セマフォなど)の実装において、スレッドがリソースの解放を待つ際などに利用されます。
7. アセンブリ言語 (.s
ファイル)
Go言語のランタイムには、OSのシステムコールを直接呼び出すために、アセンブリ言語で書かれたコードが含まれることがあります。これは、C言語などの高級言語では実現が難しい、レジスタの直接操作や特定の呼び出し規約への厳密な準拠が必要な場合に用いられます。sys_openbsd_386.s
やsys_openbsd_amd64.s
は、それぞれ32ビット(i386)と64ビット(AMD64)アーキテクチャ向けのOpenBSDシステムコール呼び出しを定義するアセンブリファイルです。
8. C言語 (.c
ファイル)
Goランタイムの一部は、C言語で書かれています。これは、OSとのインターフェースや、Go言語自体が提供する低レベルな機能の実装に利用されます。thread_openbsd.c
は、OpenBSDにおけるスレッド関連のGoランタイムコードの一部をC言語で実装しているファイルです。
技術的詳細
このコミットは、OpenBSD 5.1カーネルにおけるthrexit
とthrsleep
システムコールのABI変更に対応するために、Goランタイムの低レベルな部分を修正しています。
OpenBSDのシステムコールは、通常、int $0x80
(i386アーキテクチャ)またはSYSCALL
(amd64アーキテクチャ)命令を使用して呼び出されます。システムコール番号はAX
レジスタに格納され、引数は特定のレジスタ(i386ではスタック、amd64ではDI, SI, DX, R10, R8, R9など)に渡されます。
コミットの変更点を見ると、主に以下の点が修正されています。
-
threxit
システムコール:- OpenBSD 5.1では、
threxit
システムコールが__threxit
という名前で提供され、引数リストが変更された可能性があります。特に、notdead
という新しい引数が追加されたようです。 - 32ビット版 (
sys_openbsd_386.s
) では、runtime·exit1
関数内でsys_threxit
のシステムコール番号(302)を呼び出す前に、スタックに$0
と$0
(notdead
引数に対応する可能性のある値)をプッシュしています。これは、新しいABIが追加の引数を期待していることを示唆しています。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·rfork_thread
およびruntime·exit1
関数内でMOVQ $0, DI
という命令が追加されています。これは、DI
レジスタ(第一引数)に0
をセットしており、これが新しいnotdead
引数に対応すると考えられます。
- OpenBSD 5.1では、
-
thrsleep
システムコール:- OpenBSD 5.1では、
thrsleep
システムコールが__thrsleep
という名前で提供され、引数リストにconst int32 *abort
という新しい引数が追加されたようです。 - 32ビット版 (
sys_openbsd_386.s
) では、runtime·thrsleep
のシステムコール番号(300)の呼び出し自体は変わっていませんが、C言語側の定義 (thread_openbsd.c
) で引数が増えています。これは、アセンブリ側でスタックに積む引数の数が増えたことを意味します。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·thrsleep
関数内でMOVQ 40(SP), R8
という命令が追加されています。これは、スタックのオフセット40の位置にある値(abort
引数に対応)をR8
レジスタ(第五引数)にロードしていることを示しています。
- OpenBSD 5.1では、
-
C言語側の関数プロトタイプ変更:
src/pkg/runtime/thread_openbsd.c
ファイルでは、runtime·thrsleep
関数のプロトタイプがextern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock);
からextern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort);
に変更されています。これにより、C言語側からthrsleep
を呼び出す際に、新しいabort
引数を渡すことができるようになります。runtime·semasleep
関数内でのruntime·thrsleep
の呼び出しも、新しい引数nil
を追加するように修正されています。これは、この特定のコンテキストではabort
引数が不要であることを示しています。
これらの変更は、OpenBSDカーネルのシステムコール実装が変更された際に、Goランタイムがその変更に追従し、正しい引数でシステムコールを呼び出すようにするためのものです。後方互換性を保つために、古いカーネルでは無視されるか、デフォルト値として扱われるような引数を追加していると考えられます。
コアとなるコードの変更箇所
src/pkg/runtime/sys_openbsd_386.s
TEXT runtime·exit1(SB)
:- スタックに
$0, 0(SP)
と$0, 4(SP)
(arg 1 - notdead
)を追加。 - コメントを
sys_threxit
からsys___threxit
に変更。
- スタックに
TEXT runtime·thrsleep(SB)
:- コメントを
sys_thrsleep
からsys___thrsleep
に変更。
- コメントを
TEXT runtime·thrwakeup(SB)
:- コメントを
sys_thrwakeup
からsys___thrwakeup
に変更。
- コメントを
- その他、
crash
コメントのタブ文字の修正。
src/pkg/runtime/sys_openbsd_amd64.s
TEXT runtime·rfork_thread(SB)
:MOVQ $0, DI
(arg 1 - notdead
)を追加。- コメントを
sys_threxit
からsys___threxit
に変更。
TEXT runtime·thrsleep(SB)
:MOVQ 40(SP), R8
(arg 5 - abort
)を追加。- コメントを
sys_thrsleep
からsys___thrsleep
に変更。
TEXT runtime·thrwakeup(SB)
:- コメントを
sys_thrwakeup
からsys___thrwakeup
に変更。
- コメントを
TEXT runtime·exit1(SB)
:MOVQ $0, DI
(arg 1 - notdead
)を追加。- コメントを
sys_threxit
からsys___threxit
に変更。
- その他、コメントのタブ文字の修正。
src/pkg/runtime/thread_openbsd.c
extern int32 runtime·thrsleep(...)
の関数プロトタイプにconst int32 *abort
引数を追加。runtime·semasleep
関数内のruntime·thrsleep
呼び出しにnil
を追加。
コアとなるコードの解説
このコミットのコアとなる変更は、OpenBSDのシステムコール呼び出し規約の変更にGoランタイムが適応するためのものです。
アセンブリコード (.s
ファイル) の変更
アセンブリファイル(sys_openbsd_386.s
とsys_openbsd_amd64.s
)は、GoランタイムがOpenBSDカーネルのシステムコールを直接呼び出すための低レベルなコードを含んでいます。
-
threxit
(システムコール番号 302):- 32ビット版 (
sys_openbsd_386.s
) では、runtime·exit1
関数がthrexit
システムコールを呼び出す前に、スタックに2つのゼロ値($0, 0(SP)
と$0, 4(SP)
)をプッシュしています。これは、OpenBSD 5.1の__threxit
システムコールが、以前のバージョンにはなかった新しい引数(おそらくnotdead
というフラグ)を期待するようになったためです。スタックに引数を積むことで、システムコールが期待するABIに適合させます。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·rfork_thread
とruntime·exit1
関数内でMOVQ $0, DI
という命令が追加されています。64ビットシステムでは、システムコールの最初の引数は通常DI
レジスタに渡されます。この変更は、__threxit
が新しい第一引数(notdead
)を期待するようになったため、その引数に0
をセットしていることを意味します。
- 32ビット版 (
-
thrsleep
(システムコール番号 300):- 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·thrsleep
関数内でMOVQ 40(SP), R8
という命令が追加されています。これは、スタックのオフセット40バイトの位置にある値(abort
引数)をR8
レジスタにロードしています。64ビットシステムでは、システムコールの引数は通常、DI
,SI
,DX
,R10
,R8
,R9
の順にレジスタに渡されます。R8
は第五引数に対応するため、thrsleep
が新しい第五引数(abort
)を期待するようになったことを示しています。
- 64ビット版 (
これらのアセンブリレベルの変更は、GoランタイムがOpenBSD 5.1カーネルの新しいABIに準拠し、システムコールに正しい数の引数を正しいレジスタまたはスタック位置に渡すことを保証します。
C言語コード (thread_openbsd.c
) の変更
src/pkg/runtime/thread_openbsd.c
ファイルは、GoランタイムのOpenBSD固有のスレッド関連ロジックをC言語で実装しています。
runtime·thrsleep
関数のプロトタイプにconst int32 *abort
という新しい引数が追加されました。これは、C言語側からthrsleep
システムコールを呼び出す際に、この新しい引数を渡す必要があることを示しています。runtime·semasleep
関数内でのruntime·thrsleep
の呼び出しも、新しい引数nil
を追加するように修正されています。semasleep
はセマフォの待機処理を行う関数であり、このコンテキストではabort
引数(おそらくスリープを中断するためのポインタ)は不要であるため、nil
が渡されています。
これらのC言語レベルの変更は、Goランタイムのより高レベルな部分が、更新されたthrsleep
システムコールの新しいABIに準拠して呼び出しを行うことを可能にします。アセンブリコードとCコードの両方で変更が行われているのは、システムコール呼び出しの低レベルな詳細と、それをGoランタイムのロジックに統合する高レベルなインターフェースの両方を調整する必要があるためです。
全体として、このコミットは、GoランタイムがOpenBSD 5.1カーネルの進化するABIに追従し、異なるバージョンのOpenBSD上でも安定して動作することを保証するための重要なメンテナンス作業です。
関連リンク
- Go Issue #3311: https://github.com/golang/go/issues/3311 (このコミットによって修正された問題の詳細が記載されている可能性があります)
- Go CL 5777079: https://golang.org/cl/5777079 (このコミットに対応するGoのコードレビューリンク)
参考にした情報源リンク
- OpenBSD システムコール: 一般的なOpenBSDのシステムコールに関するドキュメントやマニュアルページ。
- Go言語のランタイムソースコード: 特に
src/pkg/runtime
ディレクトリ内のOS固有のアセンブリおよびCコード。 - ABIの概念: オペレーティングシステムやプロセッサアーキテクチャにおけるABIの定義と重要性に関する一般的な情報。
- Go言語のIssueトラッカー: Goプロジェクトのバグ報告や機能要求が管理されている場所。
- Go言語のコードレビューシステム (Gerrit): Goプロジェクトの変更がレビューされるプラットフォーム。
[インデックス 12877] ファイルの概要
このコミットは、Go言語のランタイムがOpenBSDオペレーティングシステム上でスレッド関連のシステムコール(threxit
とthrsleep
)を扱う方法を更新するものです。具体的には、OpenBSD 5.1カーネルのABI(Application Binary Interface)変更に対応するために、これらのシステムコールの呼び出し規約を調整しています。この変更は、古いカーネルとの後方互換性を維持しつつ、新しいカーネル環境での正しい動作を保証することを目的としています。
コミット
commit 8cea1bf1022272ee12fc03ef939a2ea1201d34d1
Author: Joel Sing <jsing@google.com>
Date: Wed Apr 11 22:02:08 2012 +1000
runtime: update openbsd thread related syscalls to match kernel
Update the threxit and thrsleep syscalls to match the ABI of the
OpenBSD 5.1 kernel. These changes are backwards compatible with
older kernels.
Fixes #3311.
R=golang-dev, rsc, devon.odell
CC=golang-dev
https://golang.org/cl/5777079
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8cea1bf1022272ee12fc03ef939a2ea1201d34d1
元コミット内容
GoランタイムにおけるOpenBSDのスレッド関連システムコールをカーネルに合わせるための更新。
OpenBSD 5.1カーネルのABIに合わせるため、threxit
とthrsleep
システムコールを更新。これらの変更は古いカーネルとも後方互換性がある。
Go Issue #3311を修正。
変更の背景
この変更の背景には、OpenBSDオペレーティングシステムのカーネルにおけるシステムコール(syscall)のABI(Application Binary Interface)の変更があります。特にOpenBSD 5.1カーネルでは、スレッドの終了(threxit
)とスレッドの待機(thrsleep
)に関連するシステムコールの呼び出し規約が変更されました。
Go言語のランタイムは、OSの低レベルな機能(スレッド管理、メモリ管理など)を直接利用するために、システムコールを頻繁に呼び出します。OSのABIが変更されると、Goランタイムが期待するシステムコールの引数の渡し方や戻り値の形式がOS側の実装と合わなくなり、プログラムが正しく動作しなくなる可能性があります。
このコミットは、GoランタイムがOpenBSD 5.1以降のカーネルでも正しくスレッドを管理できるように、これらのシステムコールの呼び出し規約をGoランタイム側で調整することを目的としています。同時に、古いOpenBSDカーネルとの後方互換性も維持することが重要な要件でした。これは、Goプログラムが異なるバージョンのOpenBSD上で動作することを保証するためです。
また、コミットメッセージに「Fixes #3311」とあることから、この変更はGoのIssueトラッカーで報告されていた特定のバグや問題(おそらくOpenBSD 5.1上でのGoプログラムのクラッシュや誤動作)を解決するために行われたことがわかります。Web検索の結果からも、OpenBSD 5.1でthrexit()
の実装がint$80
命令から直接syscallに変換され、NULL
ポインタを引数として期待するように変更されたことが確認できます。
前提知識の解説
1. システムコール (System Call)
システムコールは、オペレーティングシステム(OS)のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。プログラムがファイルを開く、メモリを割り当てる、ネットワーク通信を行う、スレッドを作成・管理するといったOSの機能を利用する際には、直接ハードウェアにアクセスするのではなく、システムコールを介してカーネルに処理を依頼します。
システムコールは通常、特定の番号(システムコール番号)と引数によって識別され、OSによって定義されたABIに従って呼び出されます。
2. ABI (Application Binary Interface)
ABIは、コンパイルされたプログラム(バイナリ)が、OSやライブラリとどのようにやり取りするかを定義する低レベルなインターフェースです。具体的には、以下の要素を規定します。
- システムコールの呼び出し規約: システムコールを呼び出す際に、引数をどのレジスタに格納するか、スタックにどのように積むか、戻り値をどのレジスタで受け取るかなど。
- データ構造のメモリレイアウト: 構造体や共用体などのデータ型がメモリ上でどのように配置されるか。
- 関数呼び出し規約: 関数を呼び出す際の引数の渡し方、スタックフレームの管理、戻り値の受け取り方など。
- レジスタの使用規約: 関数呼び出し前後でどのレジスタが保存されるべきかなど。
ABIが変更されると、古いABIでコンパイルされたバイナリは新しいABIのOS上で正しく動作しない可能性があります。
3. OpenBSD
OpenBSDは、セキュリティを最優先に設計されたUNIX系オペレーティングシステムです。厳格なコードレビューとセキュリティ機能の実装で知られています。Go言語のランタイムは、様々なOSに対応するために、各OS固有のシステムコールやABIに対応するコードを含んでいます。
4. Goランタイム (Go Runtime)
Go言語のプログラムは、Goランタイムと呼ばれる実行環境上で動作します。Goランタイムは、ガベージコレクション、スケジューラ(ゴルーチンの管理)、メモリ管理、システムコールへの低レベルなインターフェースなど、Goプログラムの実行に必要な多くの機能を提供します。OS固有の機能にアクセスする際には、GoランタイムがそのOSのABIに合わせたシステムコールを呼び出します。
5. threxit
システムコール
threxit
は、スレッドを終了させるためのシステムコールです。通常、スレッドが自身の実行を終了する際に呼び出されます。OSによっては、スレッドの終了ステータスを親プロセスや他のスレッドに通知する機能も持ちます。OpenBSD 5.1では、threxit()
の実装が変更され、NULL
ポインタを引数として期待するようになりました。
6. thrsleep
システムコール
thrsleep
は、スレッドを一時的にスリープ(待機)させるためのシステムコールです。特定の条件が満たされるまで、または指定された時間が経過するまでスレッドの実行を中断するために使用されます。これは、同期メカニズム(ミューテックス、セマフォなど)の実装において、スレッドがリソースの解放を待つ際などに利用されます。OpenBSD 5.1には、__thrsleep()
と__thrwakeup()
関数が存在し、これらは同期メカニズムで使用されるスレッドのスリープとウェイクアップのプリミティブを提供します。
7. アセンブリ言語 (.s
ファイル)
Go言語のランタイムには、OSのシステムコールを直接呼び出すために、アセンブリ言語で書かれたコードが含まれることがあります。これは、C言語などの高級言語では実現が難しい、レジスタの直接操作や特定の呼び出し規約への厳密な準拠が必要な場合に用いられます。sys_openbsd_386.s
やsys_openbsd_amd64.s
は、それぞれ32ビット(i386)と64ビット(AMD64)アーキテクチャ向けのOpenBSDシステムコール呼び出しを定義するアセンブリファイルです。
8. C言語 (.c
ファイル)
Goランタイムの一部は、C言語で書かれています。これは、OSとのインターフェースや、Go言語自体が提供する低レベルな機能の実装に利用されます。thread_openbsd.c
は、OpenBSDにおけるスレッド関連のGoランタイムコードの一部をC言語で実装しているファイルです。
技術的詳細
このコミットは、OpenBSD 5.1カーネルにおけるthrexit
とthrsleep
システムコールのABI変更に対応するために、Goランタイムの低レベルな部分を修正しています。
OpenBSDのシステムコールは、通常、int $0x80
(i386アーキテクチャ)またはSYSCALL
(amd64アーキテクチャ)命令を使用して呼び出されます。システムコール番号はAX
レジスタに格納され、引数は特定のレジスタ(i386ではスタック、amd64ではDI, SI, DX, R10, R8, R9など)に渡されます。
コミットの変更点を見ると、主に以下の点が修正されています。
-
threxit
システムコール:- OpenBSD 5.1では、
threxit
システムコールが__threxit
という名前で提供され、引数リストが変更された可能性があります。Web検索の結果から、threxit()
がNULL
ポインタを引数として期待するように変更されたことが確認できます。 - 32ビット版 (
sys_openbsd_386.s
) では、runtime·exit1
関数内でsys_threxit
のシステムコール番号(302)を呼び出す前に、スタックに$0
と$0
(notdead
引数に対応する可能性のある値)をプッシュしています。これは、新しいABIが追加の引数を期待していることを示唆しています。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·rfork_thread
およびruntime·exit1
関数内でMOVQ $0, DI
という命令が追加されています。これは、DI
レジスタ(第一引数)に0
をセットしており、これが新しいnotdead
引数に対応すると考えられます。
- OpenBSD 5.1では、
-
thrsleep
システムコール:- OpenBSD 5.1では、
thrsleep
システムコールが__thrsleep
という名前で提供され、引数リストにconst int32 *abort
という新しい引数が追加されたようです。 - 32ビット版 (
sys_openbsd_386.s
) では、runtime·thrsleep
のシステムコール番号(300)の呼び出し自体は変わっていませんが、C言語側の定義 (thread_openbsd.c
) で引数が増えています。これは、アセンブリ側でスタックに積む引数の数が増えたことを意味します。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·thrsleep
関数内でMOVQ 40(SP), R8
という命令が追加されています。これは、スタックのオフセット40の位置にある値(abort
引数に対応)をR8
レジスタ(第五引数)にロードしていることを示しています。
- OpenBSD 5.1では、
-
C言語側の関数プロトタイプ変更:
src/pkg/runtime/thread_openbsd.c
ファイルでは、runtime·thrsleep
関数のプロトタイプがextern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock);
からextern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort);
に変更されています。これにより、C言語側からthrsleep
を呼び出す際に、新しいabort
引数を渡すことができるようになります。runtime·semasleep
関数内でのruntime·thrsleep
の呼び出しも、新しい引数nil
を追加するように修正されています。これは、この特定のコンテキストではabort
引数が不要であることを示しています。
これらの変更は、OpenBSDカーネルのシステムコール実装が変更された際に、Goランタイムがその変更に追従し、正しい引数でシステムコールを呼び出すようにするためのものです。後方互換性を保つために、古いカーネルでは無視されるか、デフォルト値として扱われるような引数を追加していると考えられます。
コアとなるコードの変更箇所
src/pkg/runtime/sys_openbsd_386.s
TEXT runtime·exit1(SB)
:- スタックに
$0, 0(SP)
と$0, 4(SP)
(arg 1 - notdead
)を追加。 - コメントを
sys_threxit
からsys___threxit
に変更。
- スタックに
TEXT runtime·thrsleep(SB)
:- コメントを
sys_thrsleep
からsys___thrsleep
に変更。
- コメントを
TEXT runtime·thrwakeup(SB)
:- コメントを
sys_thrwakeup
からsys___thrwakeup
に変更。
- コメントを
- その他、
crash
コメントのタブ文字の修正。
src/pkg/runtime/sys_openbsd_amd64.s
TEXT runtime·rfork_thread(SB)
:MOVQ $0, DI
(arg 1 - notdead
)を追加。- コメントを
sys_threxit
からsys___threxit
に変更。
TEXT runtime·thrsleep(SB)
:MOVQ 40(SP), R8
(arg 5 - abort
)を追加。- コメントを
sys_thrsleep
からsys___thrsleep
に変更。
TEXT runtime·thrwakeup(SB)
:- コメントを
sys_thrwakeup
からsys___thrwakeup
に変更。
- コメントを
TEXT runtime·exit1(SB)
:MOVQ $0, DI
(arg 1 - notdead
)を追加。- コメントを
sys_threxit
からsys___threxit
に変更。
- その他、コメントのタブ文字の修正。
src/pkg/runtime/thread_openbsd.c
extern int32 runtime·thrsleep(...)
の関数プロトタイプにconst int32 *abort
引数を追加。runtime·semasleep
関数内のruntime·thrsleep
呼び出しにnil
を追加。
コアとなるコードの解説
このコミットのコアとなる変更は、OpenBSDのシステムコール呼び出し規約の変更にGoランタイムが適応するためのものです。
アセンブリコード (.s
ファイル) の変更
アセンブリファイル(sys_openbsd_386.s
とsys_openbsd_amd64.s
)は、GoランタイムがOpenBSDカーネルのシステムコールを直接呼び出すための低レベルなコードを含んでいます。
-
threxit
(システムコール番号 302):- 32ビット版 (
sys_openbsd_386.s
) では、runtime·exit1
関数がthrexit
システムコールを呼び出す前に、スタックに2つのゼロ値($0, 0(SP)
と$0, 4(SP)
)をプッシュしています。これは、OpenBSD 5.1の__threxit
システムコールが、以前のバージョンにはなかった新しい引数(Web検索の結果からNULL
ポインタを期待するようになったnotdead
というフラグ)を期待するようになったためです。スタックに引数を積むことで、システムコールが期待するABIに適合させます。 - 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·rfork_thread
とruntime·exit1
関数内でMOVQ $0, DI
という命令が追加されています。64ビットシステムでは、システムコールの最初の引数は通常DI
レジスタに渡されます。この変更は、__threxit
が新しい第一引数(notdead
)を期待するようになったため、その引数に0
をセットしていることを意味します。
- 32ビット版 (
-
thrsleep
(システムコール番号 300):- 64ビット版 (
sys_openbsd_amd64.s
) では、runtime·thrsleep
関数内でMOVQ 40(SP), R8
という命令が追加されています。これは、スタックのオフセット40バイトの位置にある値(abort
引数)をR8
レジスタにロードしています。64ビットシステムでは、システムコールの引数は通常、DI
,SI
,DX
,R10
,R8
,R9
の順にレジスタに渡されます。R8
は第五引数に対応するため、thrsleep
が新しい第五引数(abort
)を期待するようになったことを示しています。
- 64ビット版 (
これらのアセンブリレベルの変更は、GoランタイムがOpenBSD 5.1カーネルの新しいABIに準拠し、システムコールに正しい数の引数を正しいレジスタまたはスタック位置に渡すことを保証します。
C言語コード (thread_openbsd.c
) の変更
src/pkg/runtime/thread_openbsd.c
ファイルは、GoランタイムのOpenBSD固有のスレッド関連ロジックをC言語で実装しています。
runtime·thrsleep
関数のプロトタイプにconst int32 *abort
という新しい引数が追加されました。これは、C言語側からthrsleep
システムコールを呼び出す際に、この新しい引数を渡す必要があることを示しています。runtime·semasleep
関数内でのruntime·thrsleep
の呼び出しも、新しい引数nil
を追加するように修正されています。semasleep
はセマフォの待機処理を行う関数であり、このコンテキストではabort
引数(おそらくスリープを中断するためのポインタ)は不要であるため、nil
が渡されています。
これらのC言語レベルの変更は、Goランタイムのより高レベルな部分が、更新されたthrsleep
システムコールの新しいABIに準拠して呼び出しを行うことを可能にします。アセンブリコードとCコードの両方で変更が行われているのは、システムコール呼び出しの低レベルな詳細と、それをGoランタイムのロジックに統合する高レベルなインターフェースの両方を調整する必要があるためです。
全体として、このコミットは、GoランタイムがOpenBSD 5.1カーネルの進化するABIに追従し、異なるバージョンのOpenBSD上でも安定して動作することを保証するための重要なメンテナンス作業です。
関連リンク
- Go Issue #3311: https://github.com/golang/go/issues/3311 (このコミットによって修正された問題の詳細が記載されている可能性があります)
- Go CL 5777079: https://golang.org/cl/5777079 (このコミットに対応するGoのコードレビューリンク)
参考にした情報源リンク
- OpenBSD システムコール: 一般的なOpenBSDのシステムコールに関するドキュメントやマニュアルページ。
- Go言語のランタイムソースコード: 特に
src/pkg/runtime
ディレクトリ内のOS固有のアセンブリおよびCコード。 - ABIの概念: オペレーティングシステムやプロセッサアーキテクチャにおけるABIの定義と重要性に関する一般的な情報。
- Go言語のIssueトラッカー: Goプロジェクトのバグ報告や機能要求が管理されている場所。
- Go言語のコードレビューシステム (Gerrit): Goプロジェクトの変更がレビューされるプラットフォーム。
- OpenBSD 5.1
threxit()
ABI変更に関する情報: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEUWGiUaGQcvXegkqs8WrjrjJy54ZzV5XNkrwv3gW7zAHk3F8tsvO1koLMcNgo6T5y3dk7UR-B670vgxcty6OWo4_xZ5aNVneclbU9KLmoxl3heXymTjUGWb3sw0I2- - OpenBSD 5.1
__thrsleep()
と__thrwakeup()
に関する情報: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF7Jw0JBfUd2xmP-dskztIQgvHeKqEfhtmxRjZCkw_NXVhGWTTG3aJiZ9IWYT6FMRkSA8rpo1ZVrE9ND-BKTJ0hgtDPb_KgJorU6fPAu00G10bCU3kxr--Rl2rDgQ== - OpenBSD 5.1 スレッド関連システムコールに関する情報: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH4aPrULCun5u0H7wEe9mBLMoRkSEGxl1bcDlitmBicAS7lr7T-7bvCCOMPv5Q4W4KaE4_dAibNXSOvIh6uaSLnjWRbw1qvbF3z3rSRK4QWVRCFYKMAB0G6oi3Acdoi