ゲストのネイティブ実行
Windows x86-64 では、ゲストの機械語が直接実行されます。ゲストの pthread ごとにホストのワーカーがひとつ付き、Windows が FS ベースを保持しないため、ブロックする呼び出しのたびに FS ベースを戻します。
2026年10月10日 までのリポジトリノート
ゲストのスレッドごとにワーカーひとつ
ディスパッチャーは、ゲストの pthread ごとにホストのワーカーをひとつ起動し、そのスレッドの TLS を設定し、System V の引数レジスターとともに要求されたアドレスからゲストに入ります。join、detach、yield、sleep、入れ子のコールバック、scePthreadExit はすべてこの経路で戻ってきます。HLE のスレッドは、ゲストの実行がそのコンテキストを離れた後にだけ完了します。
ブリッジは、エントリーポイントが実行可能で、スタックと TLS がマップされていることを確認します。Windows の不揮発レジスター、MXCSR、x87 の制御ワードを保存し、ゲストのスタックに切り替え、ゲストの FS ベースを設定して、エントリーを呼び出します。同期的な scePthreadExit は、ゲストのフレームを捨て、ディスパッチャーが割り込みを見る前にホストの FS を戻すネイティブの脱出で抜けます。
Windows は FS ベースを捨てる
FS を一度設定するだけでは足りません。Windows は、ユーザーが書き込んだ FS ベースをコンテキストスイッチをまたいで保持しません。スリープの後、rdfsbase は再びゼロを読みます。ゲストのコードは System V の規約に従ってスレッドローカルストレージを FS に置いているため、次の FS 相対のアクセスはアドレスゼロの近くでフォールトしてしまいます。ゲストには何の誤りもありません。ゲストが頼ってよいレジスターを、ホストが捨てたのです。
そのため、ディスパッチャーはブロックする呼び出しの後で FS を戻します。待機はシーケンスを考慮した futex を使うため、ロック解除と休止の間に届いた起床は一度だけ消費され、ブロードキャストは古いシーケンスを見たすべての待機者に見え続けます。固定長の起床履歴がいっぱいになった場合、ディスパッチャーは多めに起こし、HLE にオブジェクトを確認し直させます。時間指定のスリープは専用の警告不可の遅延を使うため、関係のない起床でオーディオのワーカーが空回りすることはありません。
フォールトとほかのオペレーティングシステム
フォールトしたゲストのスレッドは封じ込めます。診断は、可能な場合にアドレスをモジュールとシンボルに結びつけ、プロセスが未処理のホストの例外で落ちる必要はありません。PS5_CPU_WAIT_DIAGNOSTICS=1 で詳細な待機のトレースが有効になります。休止中の複数のワーカーが一度に出力すると、それ自体がフレームを止めてしまうため、通常のプレイでは無効です。
ネイティブ実行には Windows x86-64 と、RDWRFSGSBASE のプロセッサー機能が必要です。Linux と macOS のビルドでもデコーダー、ローダー、HLE はコンパイルでき、ネイティブのブリッジは未対応と報告されます。ゲストのバイナリは x86-64 の機械語で、インタープリターで実行するのではありません。
実装済みのこと
- ゲストの pthread ごとにホストのワーカーひとつを使う、Windows でのネイティブな x86-64 のゲスト実行。
- System V の呼び出し、ゲストのスタック、ブロックする呼び出しの後で戻す FS。
- シーケンスを考慮した待機、封じ込めたフォールト、ホストを戻す pthread の終了。
- ネイティブ実行なしの、Linux と macOS での検査、デコード、HLE。
まだ足りないこと
- インタープリターはありません。Windows x86-64 以外のホストではゲストを実行しません。
- FS と GS のベースを書き込めない CPU は、ネイティブのブリッジに入れません。
- 出力がプレイを止めるため、詳細な待機の診断は既定で無効です。
関連するしくみ
これらのページについて