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

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

このコミットは、Go言語のsyscallパッケージにおけるNetBSD向けの定数定義を更新するものです。具体的には、mmap(2)msync(2)mlockall(2)といったメモリ管理関連のシステムコールで使用される定数と、clone(2)関連の定数をNetBSDのzerrorsファイルに含めるように変更しています。これにより、GoプログラムがNetBSD環境でこれらのシステムコールを正しく利用できるようになります。

コミット

commit 8f9844348fc66b560e5193cb402085d91f466788
Author: Joel Sing <jsing@google.com>
Date:   Tue Jan 7 23:04:17 2014 +1100

    syscall: include mmap constants in netbsd zerror* files
    
    Include the <sys/mman.h> header for NetBSD mkerrors.sh. This brings
    in constants used with mmap(2), msync(2) and mlockall(2).
    
    The regeneration of the NetBSD zerror* files also picks clone(2)
    related constants.
    
    Update #4929.
    
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/45510044

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

https://github.com/golang/go/commit/8f9844348fc66b560e5193cb402085d91f466788

元コミット内容

syscall: include mmap constants in netbsd zerror* files

NetBSD向けのmkerrors.shスクリプトに<sys/mman.h>ヘッダを含めるようにしました。これにより、mmap(2)msync(2)mlockall(2)で使用される定数が取り込まれます。

NetBSDのzerror*ファイルの再生成により、clone(2)関連の定数も取り込まれます。

Issue #4929 を更新。

変更の背景

Go言語のsyscallパッケージは、オペレーティングシステム固有のシステムコールへの低レベルなインターフェースを提供します。Goプログラムが特定のOSの機能(例えば、メモリマッピングやプロセス生成)を直接利用するためには、そのOSが定義する関連する定数(エラーコード、フラグなど)をGo側で認識している必要があります。

このコミットの背景には、NetBSD環境においてmmap(2)msync(2)mlockall(2)といったメモリ管理関連のシステムコールや、clone(2)(プロセス/スレッド生成に関連するシステムコール)を使用する際に必要な定数が、Goのsyscallパッケージに不足していたという問題があります。Goのsyscallパッケージは、各OSのCヘッダファイルから必要な定数を自動生成するスクリプト(mkerrors.shなど)を使用していますが、NetBSDの場合、これらの定数が含まれるべきヘッダファイルが適切にインクルードされていなかったため、Go側で認識されませんでした。

具体的には、GoのIssue #4929で報告された問題に対応するための変更です。この問題は、NetBSD上でmmap関連の定数がGoのsyscallパッケージに存在しないために、Goプログラムがこれらのシステムコールを正しく呼び出せないというものでした。

前提知識の解説

  • syscallパッケージ: Go言語の標準ライブラリの一つで、オペレーティングシステムが提供するシステムコールへの低レベルなインターフェースを提供します。これにより、GoプログラムはOSのカーネル機能(ファイルI/O、ネットワーク通信、プロセス管理、メモリ管理など)を直接操作できます。
  • システムコール (System Call): オペレーティングシステムのカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。例えば、ファイルの読み書き、メモリの確保、プロセスの生成などはシステムコールを通じて行われます。
  • mmap(2): Unix系OSにおけるシステムコールで、ファイルやデバイスをプロセスのアドレス空間にマッピング(割り当て)するために使用されます。これにより、ファイルの内容をメモリのように直接アクセスできるようになり、効率的なI/Oやプロセス間通信が可能になります。
  • msync(2): mmapでマッピングされたメモリ領域の内容を、対応するファイルやデバイスに同期させるためのシステムコールです。
  • mlockall(2): プロセスのアドレス空間全体、または指定された範囲のメモリを物理メモリにロックし、スワップアウトされないようにするためのシステムコールです。リアルタイムアプリケーションなどでパフォーマンスを保証するために使用されます。
  • clone(2): Linuxや一部のUnix系OSで、新しいプロセスやスレッドを作成するためのシステムコールです。fork(2)よりも細かく、親プロセスと子プロセス間で共有するリソース(メモリ空間、ファイルディスクリプタ、シグナルハンドラなど)を指定できます。
  • mkerrors.sh: Goのsyscallパッケージ内で使用されるシェルスクリプトで、各OSのCヘッダファイルからシステムコール関連の定数(エラーコード、フラグなど)を抽出し、Goのソースコード(zerrors_*.goファイル)として自動生成するために使われます。これにより、GoプログラムがOS固有の定数をGoのコード内で利用できるようになります。
  • zerrors_*.goファイル: mkerrors.shスクリプトによって自動生成されるGoのソースファイルです。これには、特定のOSアーキテクチャ(例: zerrors_netbsd_386.gozerrors_netbsd_amd64.go)向けのシステムコール定数が定義されています。ファイル名のzは、これらのファイルが自動生成されたものであり、手動で編集すべきではないことを示す慣例的なプレフィックスです。
  • <sys/mman.h>: Unix系OSのC言語ヘッダファイルで、mmapmsyncmlockallなどのメモリマッピング関連のシステムコールや、それらで使用される定数(MAP_SHARED, MAP_PRIVATE, PROT_READ, PROT_WRITEなど)が定義されています。

技術的詳細

Goのsyscallパッケージは、クロスプラットフォームな互換性を保ちつつ、各OSの低レベルな機能にアクセスできるように設計されています。この目的を達成するため、Goは各OSのCヘッダファイルから必要な定数を自動的に抽出し、Goのコードとして生成するメカニズムを持っています。このメカニズムの中心となるのがmkerrors.shのようなスクリプトです。

このコミットでは、NetBSD環境におけるこの自動生成プロセスに焦点を当てています。

  1. ヘッダファイルの追加: src/pkg/syscall/mkerrors.shスクリプトのincludes_NetBSD変数に、新たに<sys/mman.h>が追加されました。この変数は、NetBSD向けのzerrorsファイルを生成する際に、Cコンパイラがインクルードすべきヘッダファイルを指定します。<sys/mman.h>は、mmap(2)msync(2)mlockall(2)といったメモリ管理関連のシステムコールで使用される重要な定数(例: MAP_ANON, MAP_PRIVATE, PROT_READ, PROT_WRITE, MS_ASYNC, MS_SYNCなど)を定義しています。
  2. 定数の自動取り込み: mkerrors.shスクリプトが実行されると、追加された<sys/mman.h>を通じて、これらのメモリ管理関連の定数がNetBSDのzerrors_netbsd_386.goおよびzerrors_netbsd_amd64.goファイルに自動的に取り込まれます。これにより、Goのsyscallパッケージがこれらの定数をGoのコードとして認識し、利用できるようになります。
  3. clone(2)関連定数の取り込み: コミットメッセージに「The regeneration of the NetBSD zerror* files also picks clone(2) related constants.」とあるように、この変更によってclone(2)関連の定数も同時に取り込まれています。これは、clone(2)関連の定数が、既存のインクルードパスや、<sys/mman.h>のインクルードによって間接的に利用可能になった他のヘッダファイルに含まれていたためと考えられます。具体的には、CLONE_CSIGNAL, CLONE_FILES, CLONE_FS, CLONE_PID, CLONE_PTRACE, CLONE_SIGHAND, CLONE_VFORK, CLONE_VMといった定数が追加されています。これらの定数は、clone(2)システムコールを呼び出す際に、新しいプロセス/スレッドの動作やリソース共有の挙動を制御するために使用されます。

この変更により、GoプログラムはNetBSD上でより広範なシステムコール機能を、Goのsyscallパッケージを通じて直接、かつ型安全に利用できるようになります。これは、Goが様々なOS環境でシステムプログラミングを行う上での互換性と機能性を向上させる上で重要なステップです。

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

このコミットによる主要なコード変更は以下の3つのファイルにわたります。

  1. src/pkg/syscall/mkerrors.sh:

    • NetBSD向けのインクルードリストincludes_NetBSDに、新たに#include <sys/mman.h>が追加されました。
  2. src/pkg/syscall/zerrors_netbsd_386.go:

    • CLONE_CSIGNALからCLONE_VMまでのclone(2)関連定数が追加されました。
    • MADV_DONTNEEDからMCL_FUTUREまでのmmap(2)msync(2)mlockall(2)関連定数が追加されました。
    • MS_ASYNCMS_INVALIDATEMS_SYNCといったmsync(2)関連定数が追加されました。
    • PROT_EXECからPROT_WRITEまでのメモリ保護関連定数が追加されました。
  3. src/pkg/syscall/zerrors_netbsd_amd64.go:

    • zerrors_netbsd_386.goと同様に、clone(2)mmap(2)msync(2)mlockall(2)関連の定数が追加されました。

コアとなるコードの解説

src/pkg/syscall/mkerrors.sh

--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -118,6 +118,7 @@ includes_NetBSD='\
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/event.h>
+#include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/sysctl.h>

この変更は、mkerrors.shスクリプトがNetBSD向けのzerrors_*.goファイルを生成する際に、Cコンパイラが<sys/mman.h>ヘッダをインクルードするように指示するものです。これにより、このヘッダファイル内で定義されているすべての定数(mmapmsyncmlockall関連のフラグや保護定数など)が、Goのsyscallパッケージの定数として自動的に取り込まれるようになります。これは、GoがNetBSDのメモリ管理機能をより完全にサポートするための基盤となります。

src/pkg/syscall/zerrors_netbsd_386.go および src/pkg/syscall/zerrors_netbsd_amd64.go

これらのファイルはmkerrors.shによって自動生成されるため、手動での変更は推奨されません。しかし、このコミットでは、mkerrors.shの変更によってこれらのファイルがどのように更新されたかを示しています。

追加された定数群は大きく分けて以下のカテゴリに分類されます。

  • CLONE_プレフィックスの定数:

    • CLONE_CSIGNAL, CLONE_FILES, CLONE_FS, CLONE_PID, CLONE_PTRACE, CLONE_SIGHAND, CLONE_VFORK, CLONE_VM
    • これらはclone(2)システムコールで使用されるフラグで、新しいプロセス/スレッドの作成時に、親プロセスとの間でどのリソースを共有するか、あるいは独立させるかを制御します。例えば、CLONE_VMはメモリ空間を共有することを示し、CLONE_FILESはファイルディスクリプタテーブルを共有することを示します。
  • MADV_プレフィックスの定数:

    • MADV_DONTNEED, MADV_FREE, MADV_NORMAL, MADV_RANDOM, MADV_SEQUENTIAL, MADV_SPACEAVAIL, MADV_WILLNEED
    • これらはmadvise(2)システムコールで使用されるアドバイス値です。madviseは、アプリケーションがメモリ領域のアクセスパターンをカーネルに伝えることで、カーネルがメモリ管理を最適化するのを助けます。例えば、MADV_DONTNEEDは、指定されたメモリ領域がもう必要ないことを示し、カーネルがそのページを解放してもよいことを示唆します。
  • MAP_プレフィックスの定数:

    • MAP_ALIGNMENT_16MBからMAP_ALIGNMENT_64PBMAP_ALIGNMENT_MASK, MAP_ALIGNMENT_SHIFT
    • これらはメモリマッピングのアライメント(整列)に関する定数で、特に大容量メモリの管理や特定のハードウェア要件に対応するために使用されることがあります。
    • MAP_ANON, MAP_FILE, MAP_FIXED, MAP_HASSEMAPHORE, MAP_INHERIT関連(COPY, DEFAULT, DONATE_COPY, NONE, SHARE), MAP_NORESERVE, MAP_PRIVATE, MAP_RENAME, MAP_SHARED, MAP_STACK, MAP_TRYFIXED, MAP_WIRED
    • これらはmmap(2)システムコールで使用されるフラグです。例えば、MAP_ANONはファイルではなく匿名メモリをマッピングすることを示し、MAP_PRIVATEはプライベートなコピーオンライトマッピングを作成することを示します。MAP_SHAREDは複数のプロセス間で共有されるマッピングを作成します。
  • MCL_プレフィックスの定数:

    • MCL_CURRENT, MCL_FUTURE
    • これらはmlockall(2)システムコールで使用されるフラグで、現在のメモリ領域のみをロックするか、将来割り当てられるメモリ領域もロックするかを制御します。
  • MS_プレフィックスの定数:

    • MS_ASYNC, MS_INVALIDATE, MS_SYNC
    • これらはmsync(2)システムコールで使用されるフラグです。MS_ASYNCは非同期で同期を行うことを示し、MS_SYNCは同期が完了するまでブロックすることを示します。MS_INVALIDATEは、キャッシュされたデータが無効であることを示し、再読み込みを強制します。
  • PROT_プレフィックスの定数:

    • PROT_EXEC, PROT_NONE, PROT_READ, PROT_WRITE
    • これらはmmap(2)mprotect(2)システムコールで使用されるメモリ保護フラグです。メモリ領域に対する読み取り、書き込み、実行の各権限を指定します。

これらの定数がGoのsyscallパッケージに導入されることで、Go開発者はNetBSD上でより高度なメモリ管理やプロセス間通信、スレッド管理を行うアプリケーションを開発できるようになります。

関連リンク

参考にした情報源リンク