[インデックス 15798] ファイルの概要
このコミットは、Go言語のネットワーク(net
)パッケージとランタイム(runtime
)において、Linux/ARMアーキテクチャ向けにランタイム統合されたポーリング機構(pollster)を有効にする変更です。これにより、特にTCPネットワーク操作のパフォーマンスが大幅に向上しています。
コミット
commit 1d64d04da5f54f2fc0c9801c908380b633ea67d9
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Sat Mar 16 04:01:56 2013 +0800
net, runtime: enable runtime-integrated pollster on Linux/ARM.
Results from linux/arm on a Samsung Chromebook (from dfc):
localhost(~/go/src/pkg/net) % ~/go/misc/benchcmp {old,new}.txt
benchmark old ns/op new ns/op delta
BenchmarkTCP4OneShot 568840 350526 -38.38%
BenchmarkTCP4OneShot-2 359054 206708 -42.43%
BenchmarkTCP4OneShotTimeout 637464 363550 -42.97%
BenchmarkTCP4OneShotTimeout-2 374255 216695 -42.10%
BenchmarkTCP4Persistent 184974 64984 -64.87%
BenchmarkTCP4Persistent-2 109902 47195 -57.06%
BenchmarkTCP4PersistentTimeout 210039 64789 -69.15%
BenchmarkTCP4PersistentTimeout-2 124284 43374 -65.10%
BenchmarkTCP6OneShot 672278 362116 -46.14%
BenchmarkTCP6OneShot-2 383631 216400 -43.59%
BenchmarkTCP6OneShotTimeout 680740 378306 -44.43%
BenchmarkTCP6OneShotTimeout-2 397524 230152 -42.10%
BenchmarkTCP6Persistent 172346 65292 -62.12%
BenchmarkTCP6Persistent-2 106229 42096 -60.37%
BenchmarkTCP6PersistentTimeout 161149 65138 -59.58%
BenchmarkTCP6PersistentTimeout-2 152276 44548 -70.75%
R=golang-dev, dave, bradfitz, dvyukov, rsc
CC=golang-dev
https://golang.org/cl/7820045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1d64d04da5f54f2fc0c9801c908380b633ea67d9
元コミット内容
このコミットの主な内容は、Go言語のネットワークI/O処理において、Linux/ARM環境でのファイルディスクリプタ(FD)のポーリングメカニズムを、Goランタイムに統合されたepoll
ベースの実装に切り替えることです。
具体的には、以下の変更が含まれています。
src/pkg/net/fd_linux.go
ファイルの削除。このファイルは、Go言語レベルでepoll
をラップしてFDのポーリングを行っていた実装を含んでいました。src/pkg/net/fd_poll_runtime.go
およびsrc/pkg/net/fd_poll_unix.go
のビルドタグの変更。これにより、Linux/ARM環境がfd_poll_runtime.go
(ランタイム統合ポーリング)を使用するように切り替わり、fd_poll_unix.go
(従来のポーリング)からは除外されます。src/pkg/runtime/defs_linux_arm.h
にepoll
関連の定数(EPOLLIN
,EPOLLOUT
など)とEpollEvent
構造体の定義を追加。src/pkg/runtime/netpoll.goc
およびsrc/pkg/runtime/netpoll_epoll.c
のビルドタグの変更。これにより、Linux/ARM環境がnetpoll_epoll.c
(epoll
ベースのネットワークポーリング)を使用するように切り替わります。src/pkg/runtime/netpoll_stub.c
のビルドタグの変更。Linux/ARMがスタブ実装から除外されます。src/pkg/runtime/sys_linux_arm.s
にepoll_create
,epoll_ctl
,epoll_wait
,epoll_create1
,fcntl
といったepoll
関連のシステムコールを呼び出すためのアセンブリコードを追加。
コミットメッセージには、Samsung Chromebook(Linux/ARM)上でのベンチマーク結果が示されており、TCPの各種ベンチマークにおいて、旧バージョンと比較して38%から70%以上という大幅なパフォーマンス改善が確認されています。これは、Go言語のネットワークI/Oが、より効率的なepoll
メカニズムを直接利用できるようになったことによるものです。
変更の背景
Go言語の初期のバージョンでは、異なるOSやアーキテクチャに対応するため、ネットワークI/Oのポーリングメカニズムが抽象化されていました。Linux環境では、epoll
が利用可能であるにもかかわらず、一部のアーキテクチャ(特にARM)では、Go言語のランタイムに直接統合されたepoll
ベースのポーリングが有効になっていませんでした。
このコミットが行われた2013年当時、ARMアーキテクチャはモバイルデバイスや組み込みシステムだけでなく、サーバー分野でもその存在感を増し始めていました。Go言語がこれらのプラットフォームで高性能なネットワークアプリケーションを構築するためには、基盤となるI/Oメカニズムの最適化が不可欠でした。
従来のGo言語レベルでのepoll
ラッパー(fd_linux.go
のようなファイルで実装されていたもの)は、Goランタイムのスケジューラと直接連携していなかったため、コンテキストスイッチのオーバーヘッドや、I/Oブロッキング時のGoroutineのスケジューリング効率に課題がありました。
このコミットの目的は、Linux/ARM環境においても、他の主要なLinuxアーキテクチャ(x86, amd64)と同様に、Goランタイムが直接epoll
システムコールを呼び出し、GoroutineのI/Oブロッキングとアンブロッキングを効率的に管理する「ランタイム統合ポーリング」を有効にすることでした。これにより、ネットワークI/Oのレイテンシが削減され、スループットが向上し、全体的なアプリケーションのパフォーマンスが大幅に改善されることが期待されました。
前提知識の解説
1. ファイルディスクリプタ (File Descriptor, FD)
Unix系OSにおいて、ファイルやソケット、パイプなどのI/Oリソースを識別するために使われる整数値です。プログラムはFDを通じてこれらのリソースにアクセスします。
2. I/O多重化 (I/O Multiplexing)
複数のI/O操作(ファイルディスクリプタ)を同時に監視し、いずれかのFDでI/O準備ができたときに通知を受け取るメカニズムです。これにより、単一のスレッドで多数のI/O操作を効率的に処理できます。主なI/O多重化メカニズムには以下があります。
select()
/poll()
: 伝統的なI/O多重化API。監視対象のFDが増えると、カーネルとユーザー空間間のデータコピー量が増え、パフォーマンスが低下する傾向があります(O(N)の複雑性)。epoll()
(Linux): Linuxカーネルが提供する高性能なI/O多重化API。select()
やpoll()
と比較して、監視対象のFD数が増えてもパフォーマンスが劣化しにくい(O(1)の複雑性)という特徴があります。これは、カーネル内部でイベントキューを管理し、準備ができたFDのみを通知するためです。
3. Go言語のGoroutineとスケジューラ
- Goroutine: Go言語の軽量な並行処理単位です。OSのスレッドよりもはるかに軽量で、数百万のGoroutineを同時に実行することも可能です。
- Goスケジューラ: Goランタイムの一部であり、Goroutineの実行を管理します。GoroutineがI/O操作などでブロックされると、スケジューラは自動的にそのGoroutineを一時停止し、他の実行可能なGoroutineにCPUを割り当てます。I/O操作が完了すると、ブロックされていたGoroutineは再び実行可能状態になり、スケジューラによって再開されます。
4. Go言語のネットワークI/Oとポーリング
Go言語の標準ライブラリ(net
パッケージなど)は、GoroutineとI/O多重化メカニズムを組み合わせて、ノンブロッキングI/Oを効率的に実現しています。
GoのネットワークI/Oは、内部的に「ネットワークポーラー(netpoller)」と呼ばれるコンポーネントを使用します。このポーラーは、OSの提供するI/O多重化API(Linuxではepoll
、macOSではkqueue
など)を利用して、多数のソケットからのイベントを効率的に監視します。
Goroutineがソケットからの読み書きを試み、データが準備できていない場合、そのGoroutineはブロックされます。しかし、OSのスレッド全体がブロックされるのではなく、GoランタイムのスケジューラがそのGoroutineを「待機中」の状態にし、ポーラーにそのソケットのイベント監視を登録します。ポーラーがイベントを検知すると、スケジューラは待機中のGoroutineを「実行可能」状態に戻し、別のOSスレッドで実行を再開させます。このメカニズムにより、Goは多数の同時接続を効率的に処理できます。
5. ビルドタグ (Build Tags)
Go言語のソースコードでは、ファイルの先頭に// +build tag
のようなコメントを記述することで、特定の環境(OS、アーキテクチャなど)でのみそのファイルをコンパイルするように制御できます。例えば、// +build linux,arm
はLinux/ARM環境でのみコンパイルされることを意味します。
技術的詳細
このコミットの核心は、Linux/ARM環境におけるGo言語のネットワークI/Oパスを、Goランタイムに深く統合されたepoll
ベースのポーリングメカニズムに移行することです。
1. fd_linux.go
の削除とランタイム統合
以前のGoバージョンでは、src/pkg/net/fd_linux.go
のようなファイルが、Go言語のコード内でepoll
システムコールを直接ラップし、ファイルディスクリプタのポーリングを行っていました。これはGoのnet
パッケージの一部として機能していましたが、Goランタイムのスケジューラとは独立した形でポーリングロジックが実装されていました。
このコミットでは、fd_linux.go
が削除されます。これは、Go言語レベルでのポーリング実装が不要になったことを意味します。代わりに、src/pkg/runtime/netpoll_epoll.c
に実装されているC言語ベースのepoll
ポーリングロジックが、Linux/ARM環境でも直接利用されるようになります。このnetpoll_epoll.c
はGoランタイムの一部であり、Goroutineのスケジューリングと密接に連携しています。
2. ビルドタグによる制御
src/pkg/net/fd_poll_runtime.go
のビルドタグが// +build darwin linux,386 linux,amd64
から// +build darwin linux
に変更されました。これにより、Linux/ARMもこのファイルに含まれるランタイム統合ポーリングのインターフェースを使用するようになります。src/pkg/net/fd_poll_unix.go
のビルドタグが// +build freebsd linux,arm netbsd openbsd
から// +build freebsd netbsd openbsd
に変更されました。これにより、Linux/ARMは従来のUnix系ポーリングメカニズムから除外されます。src/pkg/runtime/netpoll.goc
のビルドタグも同様に// +build darwin linux,386 linux,amd64
から// +build darwin linux
に変更され、Linux/ARMがランタイムのネットワークポーリングロジックを使用するようになります。src/pkg/runtime/netpoll_epoll.c
のビルドタグが// +build linux,386 linux,amd64
から// +build linux
に変更され、Linux/ARMもepoll
ベースのポーリング実装を使用するようになります。src/pkg/runtime/netpoll_stub.c
のビルドタグからlinux,arm
が削除され、Linux/ARMがスタブ実装ではなく実際のポーリングメカニズムを使用するようになります。
これらのビルドタグの変更により、GoコンパイラはLinux/ARM環境でビルドする際に、Goランタイムに統合されたepoll
ポーリング関連のCコードとアセンブリコードをリンクするようになります。
3. epoll
システムコールの追加
src/pkg/runtime/defs_linux_arm.h
には、epoll
関連の定数(EPOLLIN
, EPOLLOUT
, EPOLL_CTL_ADD
など)と、epoll_wait
システムコールが返すイベント情報を格納するEpollEvent
構造体が追加されました。これらはCコードからepoll
システムコールを呼び出す際に必要となる定義です。
src/pkg/runtime/sys_linux_arm.s
には、ARMアーキテクチャのシステムコール呼び出し規約に従って、以下のepoll
関連システムコールを呼び出すためのアセンブリコードが追加されました。
SYS_epoll_create
SYS_epoll_ctl
SYS_epoll_wait
SYS_epoll_create1
SYS_fcntl
(ファイルディスクリプタのフラグ設定、特にFD_CLOEXEC
のため)
これらのアセンブリ関数は、GoランタイムのCコード(netpoll_epoll.c
など)から呼び出され、カーネルのepoll
機能と直接やり取りします。
4. パフォーマンス向上
コミットメッセージに示されているベンチマーク結果は、この変更がもたらすパフォーマンス上の大きなメリットを明確に示しています。TCPの各種ベンチマークにおいて、処理時間が大幅に短縮されています。これは、GoランタイムがI/Oイベントをより効率的に検知し、Goroutineのブロック/アンブロックを最適化できるようになったためです。特に、多数の同時接続や高頻度なI/O操作を伴うアプリケーションにおいて、この改善は顕著な効果を発揮します。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、主に以下のファイルに集中しています。
-
src/pkg/net/fd_linux.go
の削除:- このファイル全体が削除されました。これは、Go言語レベルで実装されていた
epoll
ベースのポーリングロジックが、ランタイム統合されたC言語実装に置き換えられたことを示します。
- このファイル全体が削除されました。これは、Go言語レベルで実装されていた
-
src/pkg/net/fd_poll_runtime.go
のビルドタグ変更:--- a/src/pkg/net/fd_poll_runtime.go +++ b/src/pkg/net/fd_poll_runtime.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin linux,386 linux,amd64 +// +build darwin linux package net
linux,arm
が含まれるように、linux
のみが指定されるようになりました。これにより、Linux/ARM環境でもこのファイルがコンパイルされ、ランタイム統合ポーリングのインターフェースが使用されます。
-
src/pkg/net/fd_poll_unix.go
のビルドタグ変更:--- a/src/pkg/net/fd_poll_unix.go +++ b/src/pkg/net/fd_poll_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license can be found in the LICENSE file. -// +build freebsd linux,arm netbsd openbsd +// +build freebsd netbsd openbsd package net
linux,arm
がビルドタグから削除されました。これにより、Linux/ARMは従来のUnix系ポーリングメカニズム(select
/poll
ベースの可能性が高い)から除外されます。
-
src/pkg/runtime/defs_linux_arm.h
へのepoll
関連定義の追加:--- a/src/pkg/runtime/defs_linux_arm.h +++ b/src/pkg/runtime/defs_linux_arm.h @@ -2,6 +2,7 @@ // Constants enum { +\tEINTR = 0x4,\ \tENOMEM = 0xc,\ \tEAGAIN = 0xb,\ @@ -65,6 +66,17 @@ enum { \tITIMER_VIRTUAL = 0x1,\ \tO_RDONLY = 0,\ \tO_CLOEXEC = 02000000,\ +\ +\tEPOLLIN\t\t= 0x1,\ +\tEPOLLOUT\t= 0x4,\ +\tEPOLLERR\t= 0x8,\ +\tEPOLLHUP\t= 0x10,\ +\tEPOLLRDHUP\t= 0x2000,\ +\tEPOLLET\t\t= -0x80000000,\ +\tEPOLL_CLOEXEC\t= 0x80000,\ +\tEPOLL_CTL_ADD\t= 0x1,\ +\tEPOLL_CTL_DEL\t= 0x2,\ +\tEPOLL_CTL_MOD\t= 0x3,\ }; // Types @@ -146,4 +158,11 @@ struct Sigaction {\ \tvoid *sa_restorer;\ \tuint64 sa_mask;\ };\ +\ +typedef struct EpollEvent EpollEvent;\ +struct EpollEvent {\ +\tuint32\tevents;\ +\tuint32\t_pad;\ +\tuint64\tdata;\ +};\ #pragma pack off
epoll
関連の定数(イベントフラグ、操作コード)と、epoll_wait
から返されるイベント情報を格納するEpollEvent
構造体が追加されました。これらはC言語でepoll
システムコールを扱うために必要です。
-
src/pkg/runtime/netpoll.goc
のビルドタグ変更:--- a/src/pkg/runtime/netpoll.goc +++ b/src/pkg/runtime/netpoll.goc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license can be found in the LICENSE file. -// +build darwin linux,386 linux,amd64 +// +build darwin linux package net
linux,arm
が含まれるように、linux
のみが指定されるようになりました。これにより、Linux/ARM環境でもこのファイルがコンパイルされ、ランタイムのネットワークポーリングロジックが使用されます。
-
src/pkg/runtime/netpoll_epoll.c
のビルドタグ変更:--- a/src/pkg/runtime/netpoll_epoll.c +++ b/src/pkg/runtime/netpoll_epoll.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license can be found in the LICENSE file. -// +build linux,386 linux,amd64 +// +build linux #include "runtime.h" #include "defs_GOOS_GOARCH.h"
linux,arm
が含まれるように、linux
のみが指定されるようになりました。これにより、Linux/ARM環境でもこのファイルがコンパイルされ、epoll
ベースのポーリング実装が使用されます。
-
src/pkg/runtime/netpoll_stub.c
のビルドタグ変更:--- a/src/pkg/runtime/netpoll_stub.c +++ b/src/pkg/runtime/netpoll_stub.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license can be found in the LICENSE file. -// +build freebsd linux,arm netbsd openbsd plan9 windows +// +build freebsd netbsd openbsd plan9 windows #include "runtime.h"
linux,arm
がビルドタグから削除されました。これにより、Linux/ARMはネットワークポーリングのスタブ実装ではなく、実際のepoll
ベースの実装を使用するようになります。
-
src/pkg/runtime/sys_linux_arm.s
へのシステムコール呼び出しの追加:--- a/src/pkg/runtime/sys_linux_arm.s +++ b/src/pkg/runtime/sys_linux_arm.s @@ -36,6 +36,11 @@ #define SYS_ugetrlimit (SYS_BASE + 191) #define SYS_sched_getaffinity (SYS_BASE + 242) #define SYS_clock_gettime (SYS_BASE + 263) +#define SYS_epoll_create (SYS_BASE + 250) +#define SYS_epoll_ctl (SYS_BASE + 251) +#define SYS_epoll_wait (SYS_BASE + 252) +#define SYS_epoll_create1 (SYS_BASE + 357) +#define SYS_fcntl (SYS_BASE + 55) #define ARM_BASE (SYS_BASE + 0x0f0000) @@ -371,7 +376,6 @@ cascheck: MOVW $0, R0 RET -\ TEXT runtime·casp(SB),7,$0 B runtime·cas(SB) @@ -387,3 +391,46 @@ TEXT runtime·sched_getaffinity(SB),7,$0 MOVW $SYS_sched_getaffinity, R7 SWI $0 RET +\ +// int32 runtime·epollcreate(int32 size)\ +TEXT runtime·epollcreate(SB),7,$0\ +\tMOVW\t0(FP), R0\ +\tMOVW\t$SYS_epoll_create, R7\ +\tSWI\t$0\ +\tRET\ +\ +// int32 runtime·epollcreate1(int32 flags)\ +TEXT runtime·epollcreate1(SB),7,$0\ +\tMOVW\t0(FP), R0\ +\tMOVW\t$SYS_epoll_create1, R7\ +\tSWI\t$0\ +\tRET\ +\ +// int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev)\ +TEXT runtime·epollctl(SB),7,$0\ +\tMOVW\t0(FP), R0\ +\tMOVW\t4(FP), R1\ +\tMOVW\t8(FP), R2\ +\tMOVW\t12(FP), R3\ +\tMOVW\t$SYS_epoll_ctl, R7\ +\tSWI\t$0\ +\tRET\ +\ +// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)\ +TEXT runtime·epollwait(SB),7,$0\ +\tMOVW\t0(FP), R0\ +\tMOVW\t4(FP), R1\ +\tMOVW\t8(FP), R2\ +\tMOVW\t12(FP), R3\ +\tMOVW\t$SYS_epoll_wait, R7\ +\tSWI\t$0\ +\tRET\ +\ +// void runtime·closeonexec(int32 fd)\ +TEXT runtime·closeonexec(SB),7,$0\ +\tMOVW\t0(FP), R0\t// fd\ +\tMOVW\t$2, R1\t// F_SETFD\ +\tMOVW\t$1, R2\t// FD_CLOEXEC\ +\tMOVW\t$SYS_fcntl, R7\ +\tSWI $0\ +\tRET
epoll_create
,epoll_ctl
,epoll_wait
,epoll_create1
,fcntl
といったシステムコールの番号定義が追加されました。- これらのシステムコールを呼び出すためのアセンブリ関数(
runtime·epollcreate
,runtime·epollcreate1
,runtime·epollctl
,runtime·epollwait
,runtime·closeonexec
)が追加されました。これらの関数は、GoランタイムのCコードから呼び出され、カーネルのepoll
機能と直接連携します。
コアとなるコードの解説
このコミットの主要な変更は、Go言語のネットワークI/O処理におけるLinux/ARMアーキテクチャのポーリングメカニズムを、Goランタイムに直接統合されたepoll
ベースの実装に切り替えることです。
-
fd_linux.go
の削除:- このファイルは、Go言語の
net
パッケージ内でepoll
システムコールをラップし、ファイルディスクリプタのイベントを監視する役割を担っていました。しかし、これはGoランタイムのスケジューラとは独立したGoコードとして実装されていたため、GoroutineのI/Oブロッキングとスケジューリングの連携において、オーバーヘッドや非効率性が存在しました。このファイルの削除は、Go言語レベルでのポーリング実装が不要になり、より低レベルで効率的なランタイム統合ポーリングに移行したことを意味します。
- このファイルは、Go言語の
-
ビルドタグの変更 (
fd_poll_runtime.go
,fd_poll_unix.go
,netpoll.goc
,netpoll_epoll.c
,netpoll_stub.c
):- これらの変更は、Goコンパイラに対して、Linux/ARM環境でビルドする際にどのポーリング実装を使用すべきかを指示します。
fd_poll_runtime.go
とnetpoll.goc
のビルドタグにlinux
が含まれるようになったことで、Linux/ARMもこれらのファイルに含まれるランタイム統合ポーリングのインターフェースとロジックを使用するようになります。fd_poll_unix.go
とnetpoll_stub.c
からlinux,arm
が削除されたことで、Linux/ARMは従来の汎用Unixポーリングやスタブ実装ではなく、専用のepoll
実装を使用するようになります。netpoll_epoll.c
のビルドタグにlinux
が含まれるようになったことで、Linux/ARMはepoll
ベースのネットワークポーリング実装を直接利用するようになります。このCファイルは、Goランタイムの一部としてコンパイルされ、GoのGoroutineスケジューラと密接に連携して動作します。
-
defs_linux_arm.h
とsys_linux_arm.s
におけるepoll
システムコールの追加:defs_linux_arm.h
に追加されたepoll
関連の定数とEpollEvent
構造体は、C言語でepoll
システムコールを呼び出す際に必要な定義を提供します。これにより、Cコードがepoll
の各種フラグやイベント情報を正しく解釈できるようになります。sys_linux_arm.s
に追加されたアセンブリコードは、GoランタイムのCコード(例:netpoll_epoll.c
)から、Linuxカーネルのepoll_create
,epoll_ctl
,epoll_wait
などのシステムコールを直接呼び出すためのゲートウェイを提供します。ARMアーキテクチャのシステムコール呼び出し規約に従って、レジスタに引数をセットし、SWI
(Software Interrupt) 命令でカーネルに処理を委譲します。- 特に
runtime·epollwait
のような関数は、GoroutineがI/Oでブロックされた際に、Goスケジューラがこの関数を呼び出し、カーネルにI/Oイベントの発生を待機させます。イベントが発生すると、カーネルはepoll_wait
から戻り、Goランタイムは対応するGoroutineを再開させることができます。この直接的な連携により、I/Oブロッキング時のコンテキストスイッチのオーバーヘッドが最小限に抑えられ、Goroutineのスケジューリング効率が大幅に向上します。
これらの変更により、Linux/ARM環境におけるGo言語のネットワークI/Oは、Goランタイムのスケジューラと密接に連携した、より効率的なepoll
ベースのポーリングメカニズムを利用するようになり、結果としてコミットメッセージに示されたような顕著なパフォーマンス改善が実現されました。
関連リンク
- Go言語のネットワークポーラーに関する公式ドキュメントやブログ記事(当時のものがあれば)
- Linux
epoll
システムコールのmanページ - Go言語のランタイムとスケジューラに関する解説記事
参考にした情報源リンク
- Go の netpoller の仕組み (Goのnetpollerの一般的な仕組みを理解するために参照)
- Go の netpoller の仕組み (2) - epoll (Goのepoll実装の一般的な仕組みを理解するために参照)
- epoll(7) - Linux man page (epollシステムコールの詳細を理解するために参照)
- Goのビルドタグについて (Goのビルドタグの仕組みを理解するために参照)
- Goのシステムコール呼び出しについて (Goのruntimeにおけるシステムコール呼び出しのアセンブリコードの例を理解するために参照)
- Goのランタイムとスケジューラ (GoのGoroutineとスケジューラの基本的な概念を理解するために参照)
- golang/go GitHubリポジトリ (コミットのコンテキストと関連ファイルを確認するために参照)
- Go CL 7820045 (元の変更リストを確認するために参照)