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

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

このコミットは、Go言語のビルドシステムとランタイムに関する複数の修正をまとめたものです。主に、新しいGoツールチェインへの移行に伴う調整、Cgo関連のリンカフラグの追加、およびランタイムのメモリ管理機能の拡張が含まれています。

コミット

commit e83cd7f750efe3ac2233f0589971f1e0e424382e
Author: Russ Cox <rsc@golang.org>
Date:   Tue Dec 20 17:54:40 2011 -0500

    build: a round of fixes

    TBR=r
    CC=golang-dev
    https://golang.org/cl/5503052

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

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

元コミット内容

build: a round of fixes

TBR=r
CC=golang-dev
https://golang.org/cl/5503052

変更の背景

このコミットは、Go言語のビルドシステムとランタイムにおける複数の修正を「一連の修正 (a round of fixes)」としてまとめたものです。特に注目すべき背景は、当時のGo言語開発における「新しいGoツール (new go tool)」への移行です。これは、Goのビルドプロセスやツールチェインが大きく変更されつつあった時期であり、既存のテストやビルドスクリプトが新しい環境に適応する必要がありました。

具体的には、src/pkg/debug/gosym/pclntab_test.gosrc/pkg/exp/inotify/inotify_linux_test.go の変更に見られるように、一部のテストが新しいツールチェインに対応できていないため、一時的に無効化され、将来的な対応が求められています。また、Cgo (GoとC言語の相互運用) のリンカ設定の調整や、ランタイムのメモリ管理の低レベルなインターフェースの追加は、Goランタイムの堅牢性、パフォーマンス、およびクロスプラットフォーム対応を向上させるための継続的な取り組みの一環と考えられます。

前提知識の解説

  • Goツールチェイン (Go Toolchain): Go言語のプログラムをビルド、テスト、実行、デバッグするためのツール群の総称です。go build, go test, go run などのコマンドが含まれます。Go言語の進化に伴い、これらのツールの内部実装や挙動が変更されることがあります。
  • Cgo: Go言語の機能の一つで、C言語のコードをGoプログラムから呼び出したり、GoのコードをC言語から呼び出したりするためのメカニズムです。Cgoを使用する際には、Cコンパイラやリンカのオプション(例: LDFLAGS)を指定することがよくあります。
  • ビルドタグ (+build directives): Goのソースファイルに記述される特殊なコメントで、特定の条件(OS、アーキテクチャ、Goバージョンなど)が満たされた場合にのみそのファイルをコンパイル対象とするために使用されます。これにより、プラットフォーム固有のコードを管理しやすくなります。
  • Makefile: ソフトウェアのビルドプロセスを自動化するためのツールであるmakeが使用する設定ファイルです。依存関係とコマンドを定義し、ソースコードのコンパイルやクリーンアップなどのタスクを実行します。
  • madviseシステムコール: Unix系OSで利用可能なシステムコールの一つで、プロセスがカーネルに対して、特定のメモリ領域をどのように使用するかの「アドバイス」を提供します。これにより、カーネルはメモリ管理のヒューリスティックを最適化し、パフォーマンスを向上させることができます。例えば、メモリ領域が今後アクセスされないことを示唆することで、カーネルはそのメモリをスワップアウトしたり、解放したりする判断の参考にできます。
  • lpthread: POSIXスレッドライブラリ(pthread)のリンカフラグです。Unix系システムでマルチスレッドプログラミングを行う際に必要となることが多く、スレッドの作成、同期、管理などの機能を提供します。
  • lm: 数学ライブラリ(libm)のリンカフラグです。sqrt, sin, cosなどの数学関数を使用するCコードをリンクする際に必要となることがあります。
  • lmthreads: Windows環境におけるスレッド関連のライブラリのリンカフラグです。

技術的詳細

このコミットは、Go言語のビルドとランタイムの複数の側面を改善しています。

  1. テストの適応と一時的な無効化:

    • src/pkg/debug/gosym/pclntab_test.gosrc/pkg/exp/inotify/inotify_linux_test.go では、テストが新しいGoツールチェインに対応できていないため、一時的にテストロジックをスキップし、TODOコメントを追加しています。これは、大規模なツールチェンジの際に、既存のテストスイートが一時的に機能しなくなる一般的な状況を示しています。開発者は、まず新しいツールチェインの安定化を優先し、その後でテストを適応させる戦略を取ることがあります。
    • inotify_linux_test.go+build linux タグが追加されたことで、このテストファイルがLinux環境でのみコンパイルされることが明示されました。これは、inotifyがLinux固有の機能であるため、適切なプラットフォーム分離を行うための標準的なGoのプラクティスです。
  2. ビルドクリーンアップの改善:

    • src/pkg/runtime/Makefileclean-local ターゲットに runtime_defs.goversion*.go が追加されました。これらはGoランタイムのビルドプロセス中に生成されるファイルであり、クリーンアップ時にこれらも確実に削除することで、ビルド環境の一貫性を保ち、古い生成ファイルが残存することによる潜在的な問題を回避します。
  3. Cgoリンカ設定の強化:

    • src/pkg/runtime/cgo/trigger.go に、様々なOS向けの #cgo LDFLAGS ディレクティブが追加されました。これは、CgoがGoランタイムとCライブラリをリンクする際に、特定のOSで必要となるライブラリ(例: lpthread for Unix-like systems, lm and lmthreads for Windows)を明示的に指定するためのものです。これにより、Cgoを使用するGoプログラムが異なるプラットフォームで正しくビルドおよび実行されるようになります。特に、Goランタイム自体がCgoを介してOSの低レベル機能と連携する場合、これらのリンカフラグは不可欠です。
  4. ランタイムメモリ管理の拡張:

    • src/pkg/runtime/runtime.hvoid runtime·madvise(byte*, uintptr, int32); という新しい関数宣言が追加されました。これは、Goランタイムが madvise システムコールを直接利用するためのインターフェースを公開したことを意味します。madviseは、メモリ領域のアクセスパターンに関するヒントをカーネルに提供することで、メモリ使用効率やパフォーマンスを向上させるために使用されます。例えば、Goのガベージコレクタがヒープメモリを管理する際に、不要になったメモリページをカーネルに解放するようアドバイスするために利用される可能性があります。
    • runtime·munmap 関数の第一引数の型が uint8* から byte* に変更されました。Goにおいて byteuint8 のエイリアスであるため、これは機能的な変更ではなく、コードの可読性やGoの慣習に合わせた型名の統一である可能性が高いです。

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

src/pkg/debug/gosym/pclntab_test.go

--- a/src/pkg/debug/gosym/pclntab_test.go
+++ b/src/pkg/debug/gosym/pclntab_test.go
@@ -13,7 +13,8 @@ import (
 
 func dotest() bool {
 	// For now, only works on ELF platforms.
-	return syscall.OS == "linux" && os.Getenv("GOARCH") == "amd64"
+	// TODO: convert to work with new go tool
+	return false && syscall.OS == "linux" && os.Getenv("GOARCH") == "amd64"
 }
 
 func getTable(t *testing.T) *Table {

src/pkg/exp/inotify/inotify_linux_test.go

--- a/src/pkg/exp/inotify/inotify_linux_test.go
+++ b/src/pkg/exp/inotify/inotify_linux_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build linux
+
 package inotify
 
 import (
@@ -17,6 +19,9 @@ func TestInotifyEvents(t *testing.T) {
 		t.Fatalf("NewWatcher() failed: %s", err)
 	}
 
+	t.Logf("NEEDS TO BE CONVERTED TO NEW GO TOOL") // TODO
+	return
+
 	// Add a watch for "_test"
 	err = watcher.Watch("_test")
 	if err != nil {

src/pkg/runtime/Makefile

--- a/src/pkg/runtime/Makefile
+++ b/src/pkg/runtime/Makefile
@@ -137,7 +137,7 @@ $(pkgdir)/%.h: %.h
 clean: clean-local
 
 clean-local:
-	rm -f $(AUTOHFILES)
+	rm -f $(AUTOHFILES) runtime_defs.go version*.go
 
 arch_GOARCH.h: arch_$(GOARCH).h
 	cp $^ $@

src/pkg/runtime/cgo/gcc_setenv.c

--- a/src/pkg/runtime/cgo/gcc_setenv.c
+++ b/src/pkg/runtime/cgo/gcc_setenv.c
@@ -2,6 +2,8 @@
 // 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
+
 #include "libcgo.h"
 
 #include <stdlib.h>

src/pkg/runtime/cgo/trigger.go

--- a/src/pkg/runtime/cgo/trigger.go
+++ b/src/pkg/runtime/cgo/trigger.go
@@ -7,4 +7,14 @@
 
 package cgo
 
+/*
+
+#cgo darwin LDFLAGS: -lpthread
+#cgo freebsd LDFLAGS: -lpthread
+#cgo linux LDFLAGS: -lpthread
+#cgo netbsd LDFLAGS: -lpthread
+#cgo openbsd LDFLAGS: -lpthread
+#cgo windows LDFLAGS: -lm -lmthreads
+
+*/
 import "C"

src/pkg/runtime/runtime.h

--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -635,7 +635,8 @@ void	runtime·futexwakeup(uint32*, uint32);
  * low level C-called
  */
 uint8*	runtime·mmap(byte*, uintptr, int32, int32, int32, uint32);
-void	runtime·munmap(uint8*, uintptr);
+void	runtime·munmap(byte*, uintptr);
+void	runtime·madvise(byte*, uintptr, int32);
 void	runtime·memclr(byte*, uintptr);
 void	runtime·setcallerpc(void*, void*);
 void*	runtime·getcallerpc(void*);

コアとなるコードの解説

  • src/pkg/debug/gosym/pclntab_test.go:

    • dotest() 関数内の return syscall.OS == "linux" && os.Getenv("GOARCH") == "amd64"return false && ... に変更されました。これにより、このテストは常に false を返し、実行されなくなります。
    • // TODO: convert to work with new go tool というコメントが追加され、新しいGoツールチェインへの適応が必要であることが明示されています。これは、Goのシンボルテーブル(pclntab)のフォーマットや処理方法が新しいツールで変更された可能性を示唆しています。
  • src/pkg/exp/inotify/inotify_linux_test.go:

    • ファイルの先頭に // +build linux ビルドタグが追加されました。これにより、このファイルはLinux環境でのみコンパイルされます。
    • TestInotifyEvents 関数内で t.Logf("NEEDS TO BE CONVERTED TO NEW GO TOOL") というログ出力と return が追加されました。これにより、このテストも一時的に無効化され、新しいGoツールチェインへの対応が求められています。inotifyはLinux固有のファイルシステムイベント監視機能であり、テストの無効化はツールチェインの変更がテストの実行環境や依存関係に影響を与えたことを示唆します。
  • src/pkg/runtime/Makefile:

    • clean-local ターゲットの rm -f コマンドに runtime_defs.goversion*.go が追加されました。これらはGoランタイムのビルド時に生成されるファイルであり、クリーンアッププロセスでこれらも確実に削除することで、ビルドの再現性とクリーンさを向上させます。
  • src/pkg/runtime/cgo/gcc_setenv.c:

    • ファイルの先頭に // +build darwin freebsd linux netbsd openbsd ビルドタグが追加されました。これにより、このCソースファイルは指定されたUnix系OSでのみコンパイルされます。これは、gcc_setenv.c がこれらのプラットフォームに特化した環境設定ロジックを含んでいることを示唆しています。
  • src/pkg/runtime/cgo/trigger.go:

    • Cgoのコメントブロック内に、各OS(darwin, freebsd, linux, netbsd, openbsd, windows)に対応する LDFLAGS が追加されました。
      • Unix系OSでは -lpthread (POSIXスレッドライブラリ) が指定されています。
      • Windowsでは -lm -lmthreads (数学ライブラリとWindowsスレッドライブラリ) が指定されています。
    • これらのリンカフラグは、Cgoを介してGoランタイムがCコードと連携する際に、必要なシステムライブラリを確実にリンクするために不可欠です。特に、Goの並行処理モデルがCの低レベルスレッド機能に依存する場合、lpthreadのリンクは重要です。
  • src/pkg/runtime/runtime.h:

    • void runtime·madvise(byte*, uintptr, int32); という新しい関数宣言が追加されました。これは、Goランタイムが madvise システムコールを呼び出すためのC言語側のプロトタイプです。Goランタイムがメモリ管理をより細かく制御し、OSにヒントを与えることでパフォーマンスを最適化する意図があることを示しています。
    • void runtime·munmap(uint8*, uintptr);void runtime·munmap(byte*, uintptr); に変更されました。これは、Goの byte 型がCの uint8 に対応するため、型エイリアスによる可読性向上のための変更であり、機能的な影響は小さいと考えられます。

関連リンク

参考にした情報源リンク