[インデックス 12897] ファイルの概要
このコミットは、Go言語のランタイムがOpenBSDオペレーティングシステムと連携するための定義(defs
)を更新するものです。特に、OpenBSDの低レベルスレッド作成メカニズムである__tfork
システムコールに関連する構造体__tfork
を追加し、既存の型定義を調整しています。これは、今後の変更で__tfork
が必要となることを見越した準備作業です。
コミット
- コミットハッシュ:
99fc28174369621cfe7a445cc4718fba0148745d
- 作者: Joel Sing jsing@google.com
- コミット日時: 2012年4月17日 火曜日 02:35:41 +1000
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/99fc28174369621cfe7a445cc4718fba0148745d
元コミット内容
runtime: update defs for openbsd
Update runtime defs for openbsd. Add struct __tfork, which will be
needed by an upcoming change.
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/6007050
変更の背景
Go言語のランタイムは、各オペレーティングシステム(OS)の特性に合わせて低レベルなシステムコールやデータ構造を扱う必要があります。OpenBSDは、その堅牢性とセキュリティで知られるUNIX系OSであり、独自のシステムコールやカーネルの挙動を持つことがあります。
このコミットの主な背景は、OpenBSDにおける新しいスレッド作成メカニズムである__tfork
システムコールへの対応です。Goランタイムは、ゴルーチン(goroutine)のスケジューリングやシステムスレッドの管理のために、OSが提供するスレッド関連の機能を利用します。OpenBSDでは、従来のrfork()
システムコールに代わり、より低レベルで効率的なカーネルスレッド作成のための__tfork
が導入されました。
このコミットは、GoランタイムがOpenBSD上で正しく動作し、将来的に__tfork
を利用したスレッド管理の改善を可能にするための準備として、必要なデータ構造と定数をGoのランタイム定義に追加しています。特に、__tfork
システムコールは、既存のプロセスのアドレス空間を共有する新しいカーネルスレッドを作成するために使用され、libpthread
(POSIXスレッドライブラリ)によって内部的に利用されます。Goランタイムも同様に、この低レベルなインターフェースを直接、または間接的に利用することで、OpenBSD上でのゴルーチンとOSスレッドのマッピングを最適化しようとしていると考えられます。
前提知識の解説
- Go言語のランタイム (runtime): Go言語のプログラムは、コンパイル時にGoランタイムと呼ばれる部分が組み込まれます。このランタイムは、ガベージコレクション、ゴルーチンのスケジューリング、チャネルの操作、システムコールとの連携など、Goプログラムの実行に必要な低レベルな機能を提供します。OS固有の機能にアクセスするために、各OS向けの定義ファイルやC言語で書かれたコードが含まれています。
cgo
: Go言語とC言語のコードを相互に呼び出すためのツールです。GoのコードからCのライブラリを呼び出したり、CのコードからGoの関数を呼び出したりできます。このコミットでは、cgo -cdefs
というコマンドが使われており、これはGoの構造体定義からC言語のヘッダーファイルを生成するために使用されます。これにより、GoランタイムがC言語で書かれたOS固有のコードと連携する際に、型定義の整合性を保つことができます。- OpenBSDの
__tfork
システムコール: OpenBSDに特有の低レベルなシステムコールで、既存のプロセスのアドレス空間を共有する新しいカーネルスレッドを作成するために使用されます。これは、libpthread
などのユーザーレベルスレッドライブラリが内部的に利用する主要なメカニズムです。__tfork
は、スレッド制御ブロック(TCB)のアドレスやスタックアドレスなど、新しいスレッドの実行コンテキストを設定するための様々なパラメータを許可します。成功すると、新しく作成されたスレッドでは0
を返し、呼び出し元のスレッドには新しいスレッドのIDを返します。OpenBSD 5.1で導入され、以前のrfork()
システムコールに代わるものとして位置づけられています。 defs_openbsd.go
: Goランタイム内でOpenBSD固有の定数や構造体をGoの型として定義しているファイルです。これらのGoの型は、cgo -cdefs
によってC言語のヘッダーファイル(defs_openbsd_386.h
,defs_openbsd_amd64.h
など)に変換され、C言語で書かれたランタイムコードから利用されます。- シグナルハンドリング: オペレーティングシステムは、プログラムの異常終了や外部からのイベント(例: Ctrl+C)をシグナルとしてプログラムに通知します。Goランタイムは、これらのシグナルを適切に処理し、ゴルーチンのパニックや終了、デバッグなどの機能を実現します。シグナルハンドリングには、シグナルスタック(
Sigaltstack
)やシグナルコンテキスト(Sigcontext
)などのOS固有のデータ構造が関わってきます。
技術的詳細
このコミットは、主に以下のファイルに影響を与えています。
-
src/pkg/runtime/defs_openbsd.go
:cgo
コマンドの呼び出し方法が変更されました。以前はgodefs
ツールを使用していたようですが、go tool cgo -cdefs
を使用するように更新されています。これは、Goのビルドシステムとcgo
の統合が進んだことを示唆しています。type Tfork C.struct___tfork
という行が追加され、OpenBSDのstruct __tfork
に対応するGoの型Tfork
が定義されました。これは、Goランタイムが__tfork
システムコールを呼び出す際に、その引数として渡すデータ構造をGo側で表現するために必要です。- 既存の型定義の順序が変更され、
Sigaltstack
,Sigset
,Sigcontext
,Siginfo
,Sigval
などのシグナル関連の型が再配置されました。 sfxsave64
とusavefpu
という型定義が削除されました。これらは以前、machine/fpu.h
のインクルードを避けるためのハックとしてコメントされていましたが、今回の変更で不要になったか、より適切な方法で扱われるようになったと考えられます。
-
src/pkg/runtime/defs_openbsd_386.h
およびsrc/pkg/runtime/defs_openbsd_amd64.h
:- これらのファイルは
defs_openbsd.go
からcgo -cdefs
によって自動生成されるヘッダーファイルです。 - ファイルの冒頭のコメントが
// godefs -f -m32 defs.c
から// Created by cgo -cdefs - DO NOT EDIT
に変更され、生成元が明確化されました。 struct Tfork
の定義が追加されました。これは__tfork
システムコールが期待する構造体であり、tf_tcb
(スレッド制御ブロック)、tf_tid
(スレッドID)、tf_flags
(フラグ)などのフィールドを持ちます。- 既存の定数(
PROT_NONE
,MAP_ANON
,SA_SIGINFO
,EINTR
, 各種シグナル番号など)の定義が、より整形された形式(タブ区切り)に変更されました。これは、cgo -cdefs
の出力フォーマットの変更によるものと考えられます。 Sigaltstack
,Sigcontext
,Siginfo
,StackT
,Timespec
,Timeval
,Itimerval
などの構造体定義が、フィールド名の前にbyte
やint32
などの型が明示的に記述される形式に更新されました。また、パディングバイト(Pad_cgo_0
)が追加されるなど、cgo
によるアラインメントの調整が反映されています。Sigval
の定義がunion Sigval
からtypedef byte Sigval[4];
またはtypedef byte Sigval[8];
(アーキテクチャによる)に変更されました。これは、Goのunion
の扱いがCのunion
と異なるため、cgo
がより単純なバイト配列として扱うように変換した結果と考えられます。sfxsave64
とusavefpu
に関連する定義がこれらのヘッダーファイルからも削除されました。
- これらのファイルは
-
src/pkg/runtime/signal_openbsd_386.c
およびsrc/pkg/runtime/signal_openbsd_amd64.c
:runtime·signalstack
関数内で、Sigaltstack
構造体のss_sp
フィールドに値を代入する際に、st.ss_sp = (int8*)p;
からst.ss_sp = p;
へとキャストが削除されました。これは、defs_openbsd.go
および生成されるヘッダーファイルでss_sp
の型がvoid *
またはbyte *
として適切に定義されたため、明示的なキャストが不要になったことを示しています。これにより、コードの可読性と型安全性が向上します。
これらの変更は、GoランタイムがOpenBSDの新しいスレッドモデルとより密接に連携し、将来的な機能拡張やパフォーマンス最適化の基盤を築くための重要なステップです。
コアとなるコードの変更箇所
src/pkg/runtime/defs_openbsd.go
--- a/src/pkg/runtime/defs_openbsd.go
+++ b/src/pkg/runtime/defs_openbsd.go
@@ -7,8 +7,8 @@
/*
Input to cgo.
-GOARCH=amd64 cgo -cdefs defs.go >amd64/defs.h
-GOARCH=386 cgo -cdefs defs.go >386/defs.h
+GOARCH=amd64 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_386.h
*/
package runtime
@@ -93,9 +93,12 @@ const (
ITIMER_PROF = C.ITIMER_PROF
)
+type Tfork C.struct___tfork
+
type Sigaltstack C.struct_sigaltstack
-type Sigset C.sigset_t
+type Sigcontext C.struct_sigcontext
type Siginfo C.siginfo_t
+type Sigset C.sigset_t
type Sigval C.union_sigval
type StackT C.stack_t
@@ -103,9 +106,3 @@ type StackT C.stack_t
type Timespec C.struct_timespec
type Timeval C.struct_timeval
type Itimerval C.struct_itimerval
-\n-// This is a hack to avoid pulling in machine/fpu.h.\n-type sfxsave64 struct{}\n-type usavefpu struct{}\n-\n-type Sigcontext C.struct_sigcontext
src/pkg/runtime/defs_openbsd_386.h
(一部抜粋、amd64も同様の変更)
--- a/src/pkg/runtime/defs_openbsd_386.h
+++ b/src/pkg/runtime/defs_openbsd_386.h
@@ -1,146 +1,148 @@
-// godefs -f -m32 defs.c
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_openbsd.go
-// MACHINE GENERATED - DO NOT EDIT.
-// Constants
enum {
- PROT_NONE = 0,
- PROT_READ = 0x1,
- PROT_WRITE = 0x2,
- PROT_EXEC = 0x4,
- MAP_ANON = 0x1000,
- MAP_PRIVATE = 0x2,
- MAP_FIXED = 0x10,
- SA_SIGINFO = 0x40,
- SA_RESTART = 0x2,
- SA_ONSTACK = 0x1,
- EINTR = 0x4,
- SIGHUP = 0x1,
- SIGINT = 0x2,
- SIGQUIT = 0x3,
- SIGILL = 0x4,
- SIGTRAP = 0x5,
- SIGABRT = 0x6,
- SIGEMT = 0x7,
- SIGFPE = 0x8,
- SIGKILL = 0x9,
- SIGBUS = 0xa,
- SIGSEGV = 0xb,
- SIGSYS = 0xc,
- SIGPIPE = 0xd,
- SIGALRM = 0xe,
- SIGTERM = 0xf,
- SIGURG = 0x10,
- SIGSTOP = 0x11,
- SIGTSTP = 0x12,
- SIGCONT = 0x13,
- SIGCHLD = 0x14,
- SIGTTIN = 0x15,
- SIGTTOU = 0x16,
- SIGIO = 0x17,
- SIGXCPU = 0x18,
- SIGXFSZ = 0x19,
- SIGVTALRM = 0x1a,
- SIGPROF = 0x1b,
- SIGWINCH = 0x1c,
- SIGINFO = 0x1d,
- SIGUSR1 = 0x1e,
- SIGUSR2 = 0x1f,
- FPE_INTDIV = 0x1,
- FPE_INTOVF = 0x2,
- FPE_FLTDIV = 0x3,
- FPE_FLTOVF = 0x4,
- FPE_FLTUND = 0x5,
- FPE_FLTRES = 0x6,
- FPE_FLTINV = 0x7,
- FPE_FLTSUB = 0x8,
- BUS_ADRALN = 0x1,
- BUS_ADRERR = 0x2,
- BUS_OBJERR = 0x3,
- SEGV_MAPERR = 0x1,
- SEGV_ACCERR = 0x2,
- ITIMER_REAL = 0,
- ITIMER_VIRTUAL = 0x1,
- ITIMER_PROF = 0x2,
-};
+\tPROT_NONE\t= 0x0,
+\tPROT_READ\t= 0x1,
+\tPROT_WRITE\t= 0x2,
+\tPROT_EXEC\t= 0x4,
-// Types
-#pragma pack on
+\tMAP_ANON\t= 0x1000,
+\tMAP_PRIVATE\t= 0x2,
+\tMAP_FIXED\t= 0x10,
-typedef struct Sigaltstack Sigaltstack;
-struct Sigaltstack {\n-\tvoid *ss_sp;\n-\tuint32 ss_size;\n-\tint32 ss_flags;\n-};\n+\tSA_SIGINFO\t= 0x40,
+\tSA_RESTART\t= 0x2,
+\tSA_ONSTACK\t= 0x1,
+\n+\tEINTR\t= 0x4,
+\n+\tSIGHUP\t\t= 0x1,
...
+\tITIMER_PROF\t= 0x2,
+};
+\n+typedef struct Tfork Tfork;
+typedef struct Sigaltstack Sigaltstack;
+typedef struct Sigcontext Sigcontext;
typedef struct Siginfo Siginfo;
-struct Siginfo {\n-\tint32 si_signo;\n-\tint32 si_code;\n-\tint32 si_errno;\n-\tbyte _data[116];\n+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+\n+#pragma pack on
+\n+struct Tfork {\n+\tbyte\t*tf_tcb;\n+\tint32\t*tf_tid;\n+\tint32\ttf_flags;\n };
\n-typedef union Sigval Sigval;\n-union Sigval {\n-\tint32 sival_int;\n-\tvoid *sival_ptr;\n+struct Sigaltstack {\n+\tbyte\t*ss_sp;\n+\tuint32\tss_size;\n+\tint32\tss_flags;\n };
+struct Sigcontext {\n+\tint32\tsc_gs;\n+\tint32\tsc_fs;\n+\tint32\tsc_es;\n+\tint32\tsc_ds;\n+\tint32\tsc_edi;\n+\tint32\tsc_esi;\n+\tint32\tsc_ebp;\n+\tint32\tsc_ebx;\n+\tint32\tsc_edx;\n+\tint32\tsc_ecx;\n+\tint32\tsc_eax;\n+\tint32\tsc_eip;\n+\tint32\tsc_cs;\n+\tint32\tsc_eflags;\n+\tint32\tsc_esp;\n+\tint32\tsc_ss;\n+\tint32\tsc_onstack;\n+\tint32\tsc_mask;\n+\tint32\tsc_trapno;\n+\tint32\tsc_err;\n+\tvoid\t*sc_fpstate;\n+};
+struct Siginfo {\n+\tint32\tsi_signo;\n+\tint32\tsi_code;\n+\tint32\tsi_errno;\n+\tbyte\t_data[116];
+};
+typedef\tuint32\tSigset;
+typedef\tbyte\tSigval[4];
\n-typedef struct StackT StackT;\n struct StackT {\n-\tvoid *ss_sp;\n-\tuint32 ss_size;\n-\tint32 ss_flags;\n+\tbyte\t*ss_sp;\n+\tuint32\tss_size;\n+\tint32\tss_flags;\n };
\n-typedef struct Timespec Timespec;\n struct Timespec {\n-\tint32 tv_sec;\n-\tint32 tv_nsec;\n+\tint32\ttv_sec;\n+\tint32\ttv_nsec;\n };
-\n-typedef struct Timeval Timeval;\n struct Timeval {\n-\tint32 tv_sec;\n-\tint32 tv_usec;\n+\tint32\ttv_sec;\n+\tint32\ttv_usec;\n };
-\n-typedef struct Itimerval Itimerval;\n struct Itimerval {\n-\tTimeval it_interval;\n-\tTimeval it_value;\n+\tTimeval\tit_interval;\n+\tTimeval\tit_value;\n };
\n-typedef void sfxsave64;\n \n-typedef void usavefpu;\n-\n-typedef struct Sigcontext Sigcontext;\
-struct Sigcontext {\n-\tint32 sc_gs;\n-\tint32 sc_fs;\n-\tint32 sc_es;\n-\tint32 sc_ds;\n-\tint32 sc_edi;\n-\tint32 sc_esi;\n-\tint32 sc_ebp;\n-\tint32 sc_ebx;\n-\tint32 sc_edx;\n-\tint32 sc_ecx;\n-\tint32 sc_eax;\n-\tint32 sc_eip;\n-\tint32 sc_cs;\n-\tint32 sc_eflags;\n-\tint32 sc_esp;\n-\tint32 sc_ss;\n-\tint32 sc_onstack;\n-\tint32 sc_mask;\n-\tint32 sc_trapno;\n-\tint32 sc_err;\n-\tusavefpu *sc_fpstate;\n-};\
#pragma pack off
src/pkg/runtime/signal_openbsd_386.c
(amd64も同様の変更)
--- a/src/pkg/runtime/signal_openbsd_386.c
+++ b/src/pkg/runtime/signal_openbsd_386.c
@@ -109,7 +109,7 @@ runtime·signalstack(byte *p, int32 n)
{
Sigaltstack st;
- st.ss_sp = (int8*)p;
+ st.ss_sp = p;
st.ss_size = n;
st.ss_flags = 0;
runtime·sigaltstack(&st, nil);
コアとなるコードの解説
このコミットの核心は、GoランタイムがOpenBSDの低レベルなスレッド作成メカニズムである__tfork
システムコールと連携できるようにするための基盤を構築することにあります。
-
Tfork
構造体の追加:src/pkg/runtime/defs_openbsd.go
にtype Tfork C.struct___tfork
が追加されたことで、GoのコードからC言語のstruct __tfork
を型安全に参照できるようになりました。これにより、Goランタイムは__tfork
システムコールを呼び出す際に、その引数として必要な情報をGoの型として扱うことが可能になります。__tfork
システムコールは、新しいカーネルスレッドを作成する際に、スレッド制御ブロック(TCB)やスレッドID、各種フラグなどの情報を受け取ります。このTfork
型は、これらの情報をGo側で表現するためのものです。 -
cgo -cdefs
への移行とヘッダーファイルの更新:defs_openbsd.go
のコメントが示すように、godefs
ツールからgo tool cgo -cdefs
への移行が行われました。これにより、Goの型定義からC言語のヘッダーファイルがより標準的な方法で生成されるようになりました。生成されたdefs_openbsd_386.h
およびdefs_openbsd_amd64.h
には、struct Tfork
の定義が追加され、GoランタイムのC言語部分が__tfork
システムコールと直接やり取りできるようになります。また、既存のシグナル関連の構造体(Sigaltstack
,Sigcontext
,Siginfo
など)の定義も、cgo
の新しい生成ロジックに合わせて調整され、パディングバイトの追加や型名の明示などが行われています。これは、GoとCの間のメモリレイアウトの整合性を保つ上で重要です。 -
シグナルハンドリングコードの簡素化:
src/pkg/runtime/signal_openbsd_386.c
およびsrc/pkg/runtime/signal_openbsd_amd64.c
におけるst.ss_sp = (int8*)p;
からst.ss_sp = p;
への変更は、Sigaltstack
構造体のss_sp
フィールドの型がGoの定義とCの定義でより一致するようになったことを示しています。これにより、不要なキャストが削除され、コードのクリーンアップと型安全性の向上が図られています。
これらの変更は、GoランタイムがOpenBSDの特定のシステムコールやデータ構造をより正確かつ効率的に利用するための基盤を強化し、将来的にOpenBSD上でのGoプログラムのパフォーマンスや安定性を向上させるための準備となります。
関連リンク
- Go CL 6007050: https://golang.org/cl/6007050
参考にした情報源リンク
- OpenBSD
__tfork
system call:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFIH2U02q1FDOaoC_5uBtxJGgf2kchr_I4mmtWqoVUDeImDAdxU8c1bqqqh7hYpMAeiAFqg8pxZZ_w4hE1i2antowktEwMQPTwO84Lf1pm1Rty0P8ZOe-5UxRGN4Q==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE6fir116LNYoWhGjLx9j9X19j9_JZABhiqzH3QR3fTOtiG9fIkld0D2E7BXakcq72lia0CjadN-NgKaZRAiBt1lIjifCWvYmZL1IBXwUXs1jZhp0tumPLtl2qAI-Xx
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG2kZFnDuoNF4iw2HmJuLO3Xa27LbPxfLxKWKnL_6BP7nfg4gXikgjE_PNsH_aX8q2XO89Y5dJq6M7ap1UdR5QAnWtkgPIxrUx_HGCiWo38iZt6pR3E4ZeafNN4PYRaFAGaF1L6EGo59hcy2IgzQaI=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGvb_XDCdU6waz7-6OXn1euSZN_6-sFkTKn6L0_cPKZB4NseCkBhMGmFAEPgk4d4pQUhwxZKY6LfGRe46eZUfLB2mbSycRYIyGayDzq6zMEjVVxAAXOfiw=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHLKQXYTp-Z8Fvnc6qXO0kzQ4WR49DEEmf8uHzL54GMib5f8VDvisoPkSHdNtezeGpLnejKerh5zXj6b54_-mdvcnAyBBKkotzNchwVMxEwAK9hxzcaoUSaLeLXbwOlkf58Clrr6A==