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

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

このコミットは、Go言語のランタイムがOpenBSDオペレーティングシステム上でスレッド関連のシステムコール(threxitthrsleep)を扱う方法を更新するものです。具体的には、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に合わせるため、threxitthrsleepシステムコールを更新。これらの変更は古いカーネルとも後方互換性がある。 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.ssys_openbsd_amd64.sは、それぞれ32ビット(i386)と64ビット(AMD64)アーキテクチャ向けのOpenBSDシステムコール呼び出しを定義するアセンブリファイルです。

8. C言語 (.c ファイル)

Goランタイムの一部は、C言語で書かれています。これは、OSとのインターフェースや、Go言語自体が提供する低レベルな機能の実装に利用されます。thread_openbsd.cは、OpenBSDにおけるスレッド関連のGoランタイムコードの一部をC言語で実装しているファイルです。

技術的詳細

このコミットは、OpenBSD 5.1カーネルにおけるthrexitthrsleepシステムコールのABI変更に対応するために、Goランタイムの低レベルな部分を修正しています。

OpenBSDのシステムコールは、通常、int $0x80(i386アーキテクチャ)またはSYSCALL(amd64アーキテクチャ)命令を使用して呼び出されます。システムコール番号はAXレジスタに格納され、引数は特定のレジスタ(i386ではスタック、amd64ではDI, SI, DX, R10, R8, R9など)に渡されます。

コミットの変更点を見ると、主に以下の点が修正されています。

  1. threxit システムコール:

    • OpenBSD 5.1では、threxitシステムコールが__threxitという名前で提供され、引数リストが変更された可能性があります。特に、notdeadという新しい引数が追加されたようです。
    • 32ビット版 (sys_openbsd_386.s) では、runtime·exit1関数内でsys_threxitのシステムコール番号(302)を呼び出す前に、スタックに$0$0notdead引数に対応する可能性のある値)をプッシュしています。これは、新しいABIが追加の引数を期待していることを示唆しています。
    • 64ビット版 (sys_openbsd_amd64.s) では、runtime·rfork_threadおよびruntime·exit1関数内でMOVQ $0, DIという命令が追加されています。これは、DIレジスタ(第一引数)に0をセットしており、これが新しいnotdead引数に対応すると考えられます。
  2. 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レジスタ(第五引数)にロードしていることを示しています。
  3. 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, DIarg 1 - notdead)を追加。
    • コメントをsys_threxitからsys___threxitに変更。
  • TEXT runtime·thrsleep(SB):
    • MOVQ 40(SP), R8arg 5 - abort)を追加。
    • コメントをsys_thrsleepからsys___thrsleepに変更。
  • TEXT runtime·thrwakeup(SB):
    • コメントをsys_thrwakeupからsys___thrwakeupに変更。
  • TEXT runtime·exit1(SB):
    • MOVQ $0, DIarg 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.ssys_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_threadruntime·exit1関数内でMOVQ $0, DIという命令が追加されています。64ビットシステムでは、システムコールの最初の引数は通常DIレジスタに渡されます。この変更は、__threxitが新しい第一引数(notdead)を期待するようになったため、その引数に0をセットしていることを意味します。
  • 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)を期待するようになったことを示しています。

これらのアセンブリレベルの変更は、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上でも安定して動作することを保証するための重要なメンテナンス作業です。

関連リンク

参考にした情報源リンク

  • OpenBSD システムコール: 一般的なOpenBSDのシステムコールに関するドキュメントやマニュアルページ。
  • Go言語のランタイムソースコード: 特にsrc/pkg/runtimeディレクトリ内のOS固有のアセンブリおよびCコード。
  • ABIの概念: オペレーティングシステムやプロセッサアーキテクチャにおけるABIの定義と重要性に関する一般的な情報。
  • Go言語のIssueトラッカー: Goプロジェクトのバグ報告や機能要求が管理されている場所。
  • Go言語のコードレビューシステム (Gerrit): Goプロジェクトの変更がレビューされるプラットフォーム。

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

このコミットは、Go言語のランタイムがOpenBSDオペレーティングシステム上でスレッド関連のシステムコール(threxitthrsleep)を扱う方法を更新するものです。具体的には、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に合わせるため、threxitthrsleepシステムコールを更新。これらの変更は古いカーネルとも後方互換性がある。 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.ssys_openbsd_amd64.sは、それぞれ32ビット(i386)と64ビット(AMD64)アーキテクチャ向けのOpenBSDシステムコール呼び出しを定義するアセンブリファイルです。

8. C言語 (.c ファイル)

Goランタイムの一部は、C言語で書かれています。これは、OSとのインターフェースや、Go言語自体が提供する低レベルな機能の実装に利用されます。thread_openbsd.cは、OpenBSDにおけるスレッド関連のGoランタイムコードの一部をC言語で実装しているファイルです。

技術的詳細

このコミットは、OpenBSD 5.1カーネルにおけるthrexitthrsleepシステムコールのABI変更に対応するために、Goランタイムの低レベルな部分を修正しています。

OpenBSDのシステムコールは、通常、int $0x80(i386アーキテクチャ)またはSYSCALL(amd64アーキテクチャ)命令を使用して呼び出されます。システムコール番号はAXレジスタに格納され、引数は特定のレジスタ(i386ではスタック、amd64ではDI, SI, DX, R10, R8, R9など)に渡されます。

コミットの変更点を見ると、主に以下の点が修正されています。

  1. threxit システムコール:

    • OpenBSD 5.1では、threxitシステムコールが__threxitという名前で提供され、引数リストが変更された可能性があります。Web検索の結果から、threxit()NULLポインタを引数として期待するように変更されたことが確認できます。
    • 32ビット版 (sys_openbsd_386.s) では、runtime·exit1関数内でsys_threxitのシステムコール番号(302)を呼び出す前に、スタックに$0$0notdead引数に対応する可能性のある値)をプッシュしています。これは、新しいABIが追加の引数を期待していることを示唆しています。
    • 64ビット版 (sys_openbsd_amd64.s) では、runtime·rfork_threadおよびruntime·exit1関数内でMOVQ $0, DIという命令が追加されています。これは、DIレジスタ(第一引数)に0をセットしており、これが新しいnotdead引数に対応すると考えられます。
  2. 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レジスタ(第五引数)にロードしていることを示しています。
  3. 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, DIarg 1 - notdead)を追加。
    • コメントをsys_threxitからsys___threxitに変更。
  • TEXT runtime·thrsleep(SB):
    • MOVQ 40(SP), R8arg 5 - abort)を追加。
    • コメントをsys_thrsleepからsys___thrsleepに変更。
  • TEXT runtime·thrwakeup(SB):
    • コメントをsys_thrwakeupからsys___thrwakeupに変更。
  • TEXT runtime·exit1(SB):
    • MOVQ $0, DIarg 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.ssys_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_threadruntime·exit1関数内でMOVQ $0, DIという命令が追加されています。64ビットシステムでは、システムコールの最初の引数は通常DIレジスタに渡されます。この変更は、__threxitが新しい第一引数(notdead)を期待するようになったため、その引数に0をセットしていることを意味します。
  • 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)を期待するようになったことを示しています。

これらのアセンブリレベルの変更は、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上でも安定して動作することを保証するための重要なメンテナンス作業です。

関連リンク

参考にした情報源リンク