Reposoup: 実行トレースのPOSIX移植
ちょっと開発環境が多すぎて収集付かなくなってきたので、棚卸しと標準化を進めることにした。そもそもRISC-VとかXtensaって本来マイナープロセッサだと思うんだけど何でこの界隈では普及してんのか。。まぁこの種の多様性のお陰でお給料が発生しているんだから文句は言ってられないけど。。
トレースツールは以前Win32向けに作っている:
POSIXは基本的にCMakeの CMAKE_C_COMPILER_LAUNCHER
とかで済ませてしまっていたので、今回Win32用のトレーサをPOSIXに移植して構成法を統一することにした。
実装方針
今回は posix_spawn
とblocking I/O + pthreadの組合せでやってみる事にした。こうすることで、 元のWin32版 の構成に近づけることができる。
posix_spawn
の活用
残念ながら Cygwinの posix_spawn
は fork
(2) の実装と等価 なので、この点はCygwinではパフォーマンスに貢献できない。LinuxやBSD、UNIX系のOSでは専用の最適化がある。特に:
- Linuxはglibc 2.24以降で
clone
(2) を使うようになった - NetBSDでは
posix_spawn
自体がsyscallになっている - Solarisでは現状での最終版である 11.4 で
spawn
(2) syscall が追加され て、posix_spawn
はそれを活用する
POSIX互換の組込みOSであるQNXも、最新バージョンで vfork
をdeprecateして posix_spawn
を推奨 している。(QNXは現在BlackBerryに買収されているが、その元々の用途であったBlackBerryは今日サービスを完全に終了する。)
posix_spawn
の使われ方
まぁ多分 ninja
程度の表現力があれば十分だろうということで、ninjaの実装を確認する。
pipe
(2) してあとは posix_spawn_file_actions_init
して fd を繋いでいくくらいのようだ。
-
stdin
-- これは/dev/null
に接続されるが、 monoがstdinを要求していた のでユニバーサルに安全なのかはちょっと自信が無い。 -
stdout
とstderr
-- これらは用意した pipe に 両方ともdup2
で接続される。確かに、ninjaは挙動としては通常の出力とstderrを区別していないようだ。実行トレースでは両者を区別する必要があるので、別々のpipeに接続する必要がある。 -
posix_spawn_file_actions_addclose
に 用意したpipe を渡す(stdout、stderrで無い方の端をcloseする)
また、 pipeの逆端は SetCloseOnExec しておく。... ninja互換ビルドシステムである Samurai は posix_spawn_file_actions_addclose で処理してるな。。まぁこちらでも同様の挙動になる。この違いは、 ninjaが posix_spawn
を使うのを後から実装した ために発生したようだ。(元のコードは fork/exec で実装されていて、こちらの場合は close on execフラグの方が一般的な実装になる)
適当にできた
ログパーサも書くか。。