[インデックス 14671] ファイルの概要
このコミットは、GoランタイムがPlan 9オペレーティングシステム上で環境変数を読み取れるようにするための getenv
関数の実装を追加します。これにより、GOMAXPROCS
や GOGC
といったGoのランタイム設定を環境変数経由で制御できるようになります。
コミット
commit 432f18221fa77b814854053e751c125c9920886c
Author: Anthony Martin <ality@pbrane.org>
Date: Mon Dec 17 11:07:40 2012 -0500
runtime: implement getenv for Plan 9
With this change the runtime can now read GOMAXPROCS, GOGC, etc.
I'm not quite sure how we missed this.
R=seed, lucio.dere, rsc
CC=golang-dev
https://golang.org/cl/6935062
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/432f18221fa77b814854053e751c125c9920886c
元コミット内容
runtime: implement getenv for Plan 9
With this change the runtime can now read GOMAXPROCS, GOGC, etc.
I'm not quite sure how we missed this.
R=seed, lucio.dere, rsc
CC=golang-dev
https://golang.org/cl/6935062
変更の背景
Goランタイムは、GOMAXPROCS
(並行実行するOSスレッドの最大数)や GOGC
(ガベージコレクションのトリガーとなるヒープ使用量の割合)など、いくつかの重要な設定を環境変数から読み取ります。しかし、このコミット以前は、Plan 9オペレーティングシステム向けのGoランタイムには、これらの環境変数を読み取るための getenv
関数が実装されていませんでした。
コミットメッセージにある「I'm not quite sure how we missed this.(なぜこれを見落としていたのか、よくわからない)」という記述は、この機能がGoランタイムの基本的な要件であり、Plan 9サポートの初期段階で実装されるべきだったにもかかわらず、これまで欠落していたことへの驚きを示しています。この欠落により、Plan 9上でGoプログラムを実行する際に、環境変数によるランタイムの挙動制御が不可能でした。このコミットは、この重要なギャップを埋めることを目的としています。
前提知識の解説
Plan 9 from Bell Labs
Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するという「すべてはファイルである」という原則を徹底しています。環境変数も例外ではなく、/env
ディレクトリ以下のファイルとして表現されます。例えば、PATH
環境変数の値は /env/PATH
ファイルの内容として読み取られます。
Goランタイム (runtime)
Go言語のプログラムは、Goランタイムと呼ばれる軽量な実行環境上で動作します。このランタイムは、ガベージコレクション、ゴルーチン(軽量スレッド)のスケジューリング、チャネル通信、システムコールインターフェースなど、Goプログラムの実行に必要な低レベルの機能を提供します。ランタイムはGo言語自体で書かれている部分が多いですが、OSとの直接的なやり取りやパフォーマンスが重要な部分はC言語やアセンブリ言語で書かれています。
環境変数 (Environment Variables)
環境変数は、オペレーティングシステムが提供する動的な名前付きの値であり、実行中のプロセスに影響を与えます。プログラムはこれらの変数を読み取って、その挙動をカスタマイズできます。Goにおいては、GOMAXPROCS
や GOGC
のようなランタイム設定の他にも、GOPATH
や GOROOT
といった開発環境に関する設定にも利用されます。
getenv
関数
getenv
は、指定された環境変数の値を取得するための標準的な関数です。Unix系システムでは通常、C標準ライブラリの一部として提供されます。Goランタイムのような低レベルのコードでは、OS固有のシステムコールやファイル操作を直接利用して、この機能を実現する必要があります。
システムコール (System Calls)
システムコールは、ユーザー空間のプログラムがオペレーティングシステムのカーネル空間のサービス(ファイルI/O、プロセス管理、メモリ管理など)を要求するためのインターフェースです。Plan 9では、ファイル操作(open
, read
, write
, seek
, close
など)もシステムコールを通じて行われます。
技術的詳細
このコミットの主要な変更点は、Plan 9における環境変数の取得方法をGoランタイムに組み込んだことです。Plan 9では、環境変数は特殊なファイルシステム /env
の下にファイルとして存在します。例えば、GOMAXPROCS
の値を取得するには、/env/GOMAXPROCS
というファイルを読み込む必要があります。
runtime·getenv
関数(C言語で記述)は、以下の手順で環境変数の値を取得します。
- ファイルパスの構築: 取得したい環境変数名(例: "GOMAXPROCS")を受け取り、それを
/env/
と結合して完全なファイルパス(例: "/env/GOMAXPROCS")を構築します。 - ファイルのオープン: 構築したパスを使用して、
runtime·open
システムコールでファイルを読み取りモード (OREAD
) で開きます。 - ファイルサイズの取得:
runtime·seek
システムコールを使用して、ファイルの末尾にシークし、ファイルのサイズ(バイト数)を取得します。これは、環境変数の値の長さを知るために必要です。 - メモリの割り当て: 取得したファイルサイズに基づいて、環境変数の値を格納するためのメモリを
runtime·malloc
で動的に割り当てます。 - 値の読み取り:
runtime·pread
システムコールを使用して、ファイルの先頭から割り当てたメモリに環境変数の値を読み込みます。 - ファイルのクローズ:
runtime·close
システムコールでファイルを閉じます。 - 値の返却: 読み取った環境変数の値が格納されたメモリへのポインタを返します。
この実装は、Plan 9の「すべてはファイルである」という哲学に忠実に従っており、環境変数を通常のファイルとして扱うことで、その値を取得しています。
また、このコミットでは、runtime·getenv
の実装を runtime.c
から env_plan9.c
および env_posix.c
に分離しています。これは、OS固有の環境変数取得ロジックをそれぞれのファイルにカプセル化し、コードのモジュール性と保守性を向上させるためのリファクタリングです。env_posix.c
は、Unix系OS(Darwin, FreeBSD, Linux, NetBSD, OpenBSD)およびWindows向けの getenv
実装を含み、既存の環境変数リストを走査して値を見つけるアプローチを取っています。
さらに、Plan 9向けの seek
システムコールを呼び出すためのアセンブリコードが sys_plan9_386.s
と sys_plan9_amd64.s
に追加されています。これは、Goランタイムが直接OSのシステムコールを呼び出すために必要な低レベルのインターフェースです。
コアとなるコードの変更箇所
このコミットでは、以下のファイルが変更されています。
src/pkg/runtime/env_plan9.c
(新規追加):- Plan 9向けの
runtime·getenv
関数が実装されています。この関数は、/env/
ディレクトリ下のファイルを読み取ることで環境変数の値を取得します。
- Plan 9向けの
src/pkg/runtime/env_posix.c
(新規追加):- POSIX互換OS(Unix系OSおよびWindows)向けの
runtime·getenv
関数が実装されています。この関数は、プロセスに渡された環境変数リストを走査して値を見つけます。 syscall·setenv_c
関数も含まれており、cgoがロードされている場合にC環境を更新する役割を担います。
- POSIX互換OS(Unix系OSおよびWindows)向けの
src/pkg/runtime/os_plan9.h
:- Plan 9固有のシステムコール関数のプロトタイプ宣言が含まれるヘッダーファイルです。
runtime·seek
関数のプロトタイプが追加されています。
- Plan 9固有のシステムコール関数のプロトタイプ宣言が含まれるヘッダーファイルです。
src/pkg/runtime/runtime.c
:- 以前
runtime.c
にあった汎用的なruntime·getenv
関数とsyscall·setenv_c
関数が削除され、OS固有のファイルに移動されました。
- 以前
src/pkg/runtime/sys_plan9_386.s
:- Plan 9/386アーキテクチャ向けの
runtime·seek
システムコールを呼び出すアセンブリコードが追加されています。
- Plan 9/386アーキテクチャ向けの
src/pkg/runtime/sys_plan9_amd64.s
:- Plan 9/AMD64アーキテクチャ向けの
runtime·seek
システムコールを呼び出すアセンブリコードが追加されています。
- Plan 9/AMD64アーキテクチャ向けの
コアとなるコードの解説
src/pkg/runtime/env_plan9.c
の runtime·getenv
関数
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "os_GOOS.h"
byte*
runtime·getenv(int8 *s)
{
int32 fd, len, n, r;
byte file[128];
byte *p;
len = runtime·findnull((byte*)s); // 環境変数名の長さを取得
if(len > sizeof file-6) // パスバッファのサイズチェック
return nil;
runtime·memclr(file, sizeof file); // バッファをクリア
runtime·memmove((void*)file, (void*)"/env/", 5); // "/env/" をコピー
runtime·memmove((void*)(file+5), (void*)s, len); // 環境変数名を結合
fd = runtime·open(file, OREAD); // ファイルを読み取りモードでオープン
if(fd < 0)
return nil;
n = runtime·seek(fd, 0, 2); // ファイルの末尾にシークしてサイズを取得 (whence=2はSEEK_END)
p = runtime·malloc(n+1); // 値を格納するメモリを割り当て (null終端のため+1)
r = runtime·pread(fd, p, n, 0); // ファイルの先頭から値を読み取り
runtime·close(fd); // ファイルをクローズ
if(r < 0)
return nil;
return p; // 読み取った値へのポインタを返す
}
このコードは、Plan 9のファイルシステムを通じて環境変数を読み取る具体的な実装です。runtime·open
, runtime·seek
, runtime·pread
, runtime·close
といった関数は、Goランタイムが提供するOS固有のシステムコールラッパーです。
src/pkg/runtime/env_posix.c
の runtime·getenv
関数
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd windows
#include "runtime.h"
Slice syscall·envs; // 環境変数リストを保持するスライス
byte*
runtime·getenv(int8 *s)
{
int32 i, j, len;
byte *v, *bs;
String* envv;
int32 envc;
bs = (byte*)s;
len = runtime·findnull(bs); // 検索する環境変数名の長さを取得
envv = (String*)syscall·envs.array; // 環境変数リストの配列
envc = syscall·envs.len; // 環境変数リストの要素数
for(i=0; i<envc; i++){ // 環境変数リストを走査
if(envv[i].len <= len) // 環境変数名が短すぎる場合はスキップ
continue;
v = envv[i].str; // 現在の環境変数文字列 (例: "GOMAXPROCS=4")
for(j=0; j<len; j++) // 環境変数名を比較
if(bs[j] != v[j])
goto nomatch; // 一致しない場合は次の環境変数へ
if(v[len] != '=') // 環境変数名の直後に'='がない場合はスキップ
goto nomatch;
return v+len+1; // '='の次の文字から値が始まるので、そのポインタを返す
nomatch:;
}
return nil; // 見つからなかった場合
}
このコードは、Unix系OSやWindowsで一般的な、プロセス起動時に渡される環境変数リスト(environ
ポインタや _environ
グローバル変数など)を走査して環境変数を検索する実装です。Plan 9とは根本的に異なるアプローチを取っています。
src/pkg/runtime/sys_plan9_386.s
および src/pkg/runtime/sys_plan9_amd64.s
の runtime·seek
これらのファイルには、Plan 9の seek
システムコールを呼び出すためのアセンブリコードが追加されています。例えば、sys_plan9_386.s
の関連部分:
TEXT runtime·seek(SB),7,$0
MOVL $39, AX // システムコール番号 39 (seek) をAXレジスタにロード
INT $64 // Plan 9のシステムコール割り込み
CMPL AX, $-1 // 戻り値が-1 (エラー) かどうかチェック
JNE 4(PC) // エラーでなければ次の命令へ
MOVL a+0(FP), CX // エラーの場合、戻り値を格納するポインタをCXにロード
MOVL AX, 0(CX) // 戻り値をポインタの先に格納
MOVL AX, 4(CX) // 64ビット値の下位32ビットも格納 (Plan 9のseekは64ビットオフセットを返す)
RET
このアセンブリコードは、GoのCコードから runtime·seek
が呼び出された際に、実際のPlan 9システムコール seek
を実行するためのゲートウェイとして機能します。システムコール番号をレジスタに設定し、特定の割り込み (INT $64
) を発行することでカーネルに処理を依頼します。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/432f18221fa77b814854053e751c125c9920886c
- Go Code Review (CL): https://golang.org/cl/6935062
参考にした情報源リンク
- Plan 9 from Bell Labs: https://9p.io/plan9/
- Go言語のランタイムに関するドキュメント (公式): https://go.dev/doc/ (特に
runtime
パッケージのドキュメント) - Goの環境変数に関するドキュメント: https://go.dev/doc/go1.1 (GOMAXPROCS, GOGCなど)
- Plan 9のシステムコールに関する情報 (例:
man 2 seek
): https://9p.io/magic/man2html/2/seek - Goのソースコード (runtimeパッケージ): https://github.com/golang/go/tree/master/src/runtime
- Goの環境変数設定に関する議論 (Go mailing listなど): 関連する議論は、Go CLのコメントやGo issue trackerで確認できます。# [インデックス 14671] ファイルの概要
このコミットは、GoランタイムがPlan 9オペレーティングシステム上で環境変数を読み取れるようにするための getenv
関数の実装を追加します。これにより、GOMAXPROCS
や GOGC
といったGoのランタイム設定を環境変数経由で制御できるようになります。
コミット
commit 432f18221fa77b814854053e751c125c9920886c
Author: Anthony Martin <ality@pbrane.org>
Date: Mon Dec 17 11:07:40 2012 -0500
runtime: implement getenv for Plan 9
With this change the runtime can now read GOMAXPROCS, GOGC, etc.
I'm not quite sure how we missed this.
R=seed, lucio.dere, rsc
CC=golang-dev
https://golang.org/cl/6935062
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/432f18221fa77b814854053e751c125c9920886c
元コミット内容
runtime: implement getenv for Plan 9
With this change the runtime can now read GOMAXPROCS, GOGC, etc.
I'm not quite sure how we missed this.
R=seed, lucio.dere, rsc
CC=golang-dev
https://golang.org/cl/6935062
変更の背景
Goランタイムは、GOMAXPROCS
(並行実行するOSスレッドの最大数)や GOGC
(ガベージコレクションのトリガーとなるヒープ使用量の割合)など、いくつかの重要な設定を環境変数から読み取ります。しかし、このコミット以前は、Plan 9オペレーティングシステム向けのGoランタイムには、これらの環境変数を読み取るための getenv
関数が実装されていませんでした。
コミットメッセージにある「I'm not quite sure how we missed this.(なぜこれを見落としていたのか、よくわからない)」という記述は、この機能がGoランタイムの基本的な要件であり、Plan 9サポートの初期段階で実装されるべきだったにもかかわらず、これまで欠落していたことへの驚きを示しています。この欠落により、Plan 9上でGoプログラムを実行する際に、環境変数によるランタイムの挙動制御が不可能でした。このコミットは、この重要なギャップを埋めることを目的としています。
前提知識の解説
Plan 9 from Bell Labs
Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するという「すべてはファイルである」という原則を徹底しています。環境変数も例外ではなく、/env
ディレクトリ以下のファイルとして表現されます。例えば、PATH
環境変数の値は /env/PATH
ファイルの内容として読み取られます。
Goランタイム (runtime)
Go言語のプログラムは、Goランタイムと呼ばれる軽量な実行環境上で動作します。このランタイムは、ガベージコレクション、ゴルーチン(軽量スレッド)のスケジューリング、チャネル通信、システムコールインターフェースなど、Goプログラムの実行に必要な低レベルの機能を提供します。ランタイムはGo言語自体で書かれている部分が多いですが、OSとの直接的なやり取りやパフォーマンスが重要な部分はC言語やアセンブリ言語で書かれています。
環境変数 (Environment Variables)
環境変数は、オペレーティングシステムが提供する動的な名前付きの値であり、実行中のプロセスに影響を与えます。プログラムはこれらの変数を読み取って、その挙動をカスタマイズできます。Goにおいては、GOMAXPROCS
や GOGC
のようなランタイム設定の他にも、GOPATH
や GOROOT
といった開発環境に関する設定にも利用されます。
getenv
関数
getenv
は、指定された環境変数の値を取得するための標準的な関数です。Unix系システムでは通常、C標準ライブラリの一部として提供されます。Goランタイムのような低レベルのコードでは、OS固有のシステムコールやファイル操作を直接利用して、この機能を実現する必要があります。
システムコール (System Calls)
システムコールは、ユーザー空間のプログラムがオペレーティングシステムのカーネル空間のサービス(ファイルI/O、プロセス管理、メモリ管理など)を要求するためのインターフェースです。Plan 9では、ファイル操作(open
, read
, write
, seek
, close
など)もシステムコールを通じて行われます。
技術的詳細
このコミットの主要な変更点は、Plan 9における環境変数の取得方法をGoランタイムに組み込んだことです。Plan 9では、環境変数は特殊なファイルシステム /env
の下にファイルとして存在します。例えば、GOMAXPROCS
の値を取得するには、/env/GOMAXPROCS
というファイルを読み込む必要があります。
runtime·getenv
関数(C言語で記述)は、以下の手順で環境変数の値を取得します。
- ファイルパスの構築: 取得したい環境変数名(例: "GOMAXPROCS")を受け取り、それを
/env/
と結合して完全なファイルパス(例: "/env/GOMAXPROCS")を構築します。 - ファイルのオープン: 構築したパスを使用して、
runtime·open
システムコールでファイルを読み取りモード (OREAD
) で開きます。 - ファイルサイズの取得:
runtime·seek
システムコールを使用して、ファイルの末尾にシークし、ファイルのサイズ(バイト数)を取得します。これは、環境変数の値の長さを知るために必要です。 - メモリの割り当て: 取得したファイルサイズに基づいて、環境変数の値を格納するためのメモリを
runtime·malloc
で動的に割り当てます。 - 値の読み取り:
runtime·pread
システムコールを使用して、ファイルの先頭から割り当てたメモリに環境変数の値を読み込みます。 - ファイルのクローズ:
runtime·close
システムコールでファイルを閉じます。 - 値の返却: 読み取った環境変数の値が格納されたメモリへのポインタを返します。
この実装は、Plan 9の「すべてはファイルである」という哲学に忠実に従っており、環境変数を通常のファイルとして扱うことで、その値を取得しています。
また、このコミットでは、runtime·getenv
の実装を runtime.c
から env_plan9.c
および env_posix.c
に分離しています。これは、OS固有の環境変数取得ロジックをそれぞれのファイルにカプセル化し、コードのモジュール性と保守性を向上させるためのリファクタリングです。env_posix.c
は、Unix系OS(Darwin, FreeBSD, Linux, NetBSD, OpenBSD)およびWindows向けの getenv
実装を含み、既存の環境変数リストを走査して値を見つけるアプローチを取っています。
さらに、Plan 9向けの seek
システムコールを呼び出すためのアセンブリコードが sys_plan9_386.s
と sys_plan9_amd64.s
に追加されています。これは、Goランタイムが直接OSのシステムコールを呼び出すために必要な低レベルのインターフェースです。
コアとなるコードの変更箇所
このコミットでは、以下のファイルが変更されています。
src/pkg/runtime/env_plan9.c
(新規追加):- Plan 9向けの
runtime·getenv
関数が実装されています。この関数は、/env/
ディレクトリ下のファイルを読み取ることで環境変数の値を取得します。
- Plan 9向けの
src/pkg/runtime/env_posix.c
(新規追加):- POSIX互換OS(Unix系OSおよびWindows)向けの
runtime·getenv
関数が実装されています。この関数は、プロセスに渡された環境変数リストを走査して値を見つけます。 syscall·setenv_c
関数も含まれており、cgoがロードされている場合にC環境を更新する役割を担います。
- POSIX互換OS(Unix系OSおよびWindows)向けの
src/pkg/runtime/os_plan9.h
:- Plan 9固有のシステムコール関数のプロトタイプ宣言が含まれるヘッダーファイルです。
runtime·seek
関数のプロトタイプが追加されています。
- Plan 9固有のシステムコール関数のプロトタイプ宣言が含まれるヘッダーファイルです。
src/pkg/runtime/runtime.c
:- 以前
runtime.c
にあった汎用的なruntime·getenv
関数とsyscall·setenv_c
関数が削除され、OS固有のファイルに移動されました。
- 以前
src/pkg/runtime/sys_plan9_386.s
:- Plan 9/386アーキテクチャ向けの
runtime·seek
システムコールを呼び出すアセンブリコードが追加されています。
- Plan 9/386アーキテクチャ向けの
src/pkg/runtime/sys_plan9_amd64.s
:- Plan 9/AMD64アーキテクチャ向けの
runtime·seek
システムコールを呼び出すアセンブリコードが追加されています。
- Plan 9/AMD64アーキテクチャ向けの
コアとなるコードの解説
src/pkg/runtime/env_plan9.c
の runtime·getenv
関数
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
#include "os_GOOS.h"
byte*
runtime·getenv(int8 *s)
{
int32 fd, len, n, r;
byte file[128];
byte *p;
len = runtime·findnull((byte*)s); // 環境変数名の長さを取得
if(len > sizeof file-6) // パスバッファのサイズチェック
return nil;
runtime·memclr(file, sizeof file); // バッファをクリア
runtime·memmove((void*)file, (void*)"/env/", 5); // "/env/" をコピー
runtime·memmove((void*)(file+5), (void*)s, len); // 環境変数名を結合
fd = runtime·open(file, OREAD); // ファイルを読み取りモードでオープン
if(fd < 0)
return nil;
n = runtime·seek(fd, 0, 2); // ファイルの末尾にシークしてサイズを取得 (whence=2はSEEK_END)
p = runtime·malloc(n+1); // 値を格納するメモリを割り当て (null終端のため+1)
r = runtime·pread(fd, p, n, 0); // ファイルの先頭から値を読み取り
runtime·close(fd); // ファイルをクローズ
if(r < 0)
return nil;
return p; // 読み取った値へのポインタを返す
}
このコードは、Plan 9のファイルシステムを通じて環境変数を読み取る具体的な実装です。runtime·open
, runtime·seek
, runtime·pread
, runtime·close
といった関数は、Goランタイムが提供するOS固有のシステムコールラッパーです。
src/pkg/runtime/env_posix.c
の runtime·getenv
関数
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd windows
#include "runtime.h"
Slice syscall·envs; // 環境変数リストを保持するスライス
byte*
runtime·getenv(int8 *s)
{
int32 i, j, len;
byte *v, *bs;
String* envv;
int32 envc;
bs = (byte*)s;
len = runtime·findnull(bs); // 検索する環境変数名の長さを取得
envv = (String*)syscall·envs.array; // 環境変数リストの配列
envc = syscall·envs.len; // 環境変数リストの要素数
for(i=0; i<envc; i++){ // 環境変数リストを走査
if(envv[i].len <= len) // 環境変数名が短すぎる場合はスキップ
continue;
v = envv[i].str; // 現在の環境変数文字列 (例: "GOMAXPROCS=4")
for(j=0; j<len; j++) // 環境変数名を比較
if(bs[j] != v[j])
goto nomatch; // 一致しない場合は次の環境変数へ
if(v[len] != '=') // 環境変数名の直後に'='がない場合はスキップ
goto nomatch;
return v+len+1; // '='の次の文字から値が始まるので、そのポインタを返す
nomatch:;
}
return nil; // 見つからなかった場合
}
このコードは、Unix系OSやWindowsで一般的な、プロセス起動時に渡される環境変数リスト(environ
ポインタや _environ
グローバル変数など)を走査して環境変数を検索する実装です。Plan 9とは根本的に異なるアプローチを取っています。
src/pkg/runtime/sys_plan9_386.s
および src/pkg/runtime/sys_plan9_amd64.s
の runtime·seek
これらのファイルには、Plan 9の seek
システムコールを呼び出すためのアセンブリコードが追加されています。例えば、sys_plan9_386.s
の関連部分:
TEXT runtime·seek(SB),7,$0
MOVL $39, AX // システムコール番号 39 (seek) をAXレジスタにロード
INT $64 // Plan 9のシステムコール割り込み
CMPL AX, $-1 // 戻り値が-1 (エラー) かどうかチェック
JNE 4(PC) // エラーでなければ次の命令へ
MOVL a+0(FP), CX // エラーの場合、戻り値を格納するポインタをCXにロード
MOVL AX, 0(CX) // 戻り値をポインタの先に格納
MOVL AX, 4(CX) // 64ビット値の下位32ビットも格納 (Plan 9のseekは64ビットオフセットを返す)
RET
このアセンブリコードは、GoのCコードから runtime·seek
が呼び出された際に、実際のPlan 9システムコール seek
を実行するためのゲートウェイとして機能します。システムコール番号をレジスタに設定し、特定の割り込み (INT $64
) を発行することでカーネルに処理を依頼します。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/432f18221fa77b814854053e751c125c9920886c
- Go Code Review (CL): https://golang.org/cl/6935062
参考にした情報源リンク
- Plan 9 from Bell Labs: https://9p.io/plan9/
- Go言語のランタイムに関するドキュメント (公式): https://go.dev/doc/ (特に
runtime
パッケージのドキュメント) - Goの環境変数に関するドキュメント: https://go.dev/doc/go1.1 (GOMAXPROCS, GOGCなど)
- Plan 9のシステムコールに関する情報 (例:
man 2 seek
): https://9p.io/magic/man2html/2/seek - Goのソースコード (runtimeパッケージ): https://github.com/golang/go/tree/master/src/runtime
- Goの環境変数設定に関する議論 (Go mailing listなど): 関連する議論は、Go CLのコメントやGo issue trackerで確認できます。