プロセスアドレス空間にはスタックとヒープがあります。関数が呼び出されるかローカル変数が宣言されると、カーネルは物理アドレスを割り当て、仮想アドレスと物理アドレスのマッピングを生成する必要があるため、これにはシステム呼び出しが必要です。どうしたの?
最初の答えは次のとおりです。 ((straceに従って)システムコールなしでスタックが大きくなることがわかりました。したがって、これはカーネルが自動的にスタックを大きくするという意味です(上記の「暗黙的」が意味するものです)。つまり、プロセスで明示的なmmap / mremapなしでスタックが大きくなります "スタックを"成長"するのがカーネルの操作である場合、なぜシステムコールが含まれないのですか?
ヒープに対する最初の答えは次のとおりです。 「再利用でmalloc呼び出しを満たすことができる場合、malloc呼び出しは必ずしもsbrkまたはmmap呼び出しにつながるわけではありません(Libcが動的メモリ割り当てを実装する方法によって異なります)。map」以前に解放されたメモリ領域。 「これはフリーリストの概念のようです。スタック割り当ても同じ概念を使用しますか?
2つの割り当てに対する私の基本的な利点は、物理メモリを割り当てる必要があり、VMAから物理メモリへのマッピングを作成してシステムコールが発生することです。最初の質問に対する回答にリンクされたMel Gormanの本を読んでみましたが、私の質問に対する意味のある回答が見つかりませんでした。
答え1
プロセスがスタックの下部にデータを書き込もうとすると、カーネルはページエラーの発生に応答してスタックを増やします。これはシステムコールとして表示されません。
システムコールはカーネルが関連する唯一の方法ではありません。システムコールはエラーと割り込みも処理します。
答え2
あなたが言及したほとんどすべては仮想メモリとは関係ありません。仮想メモリは同時に独立して発生します。スタックを増やすことに加えて。
スタックがオーバーフローすると、カーネルはスタックを増やすことができます。これは、スタックの外側にカーネル設定ページが存在しないようにすることで実現できます。プロセスがインベントリの終わりを超えてアクセスしようとすると、存在しないページを読み書きするため、ページエラーが発生します。その後、カーネルはそのページ(および可能であればより多くのページ)により多くのメモリを割り当ててマッピングし、新しい終わりを超えて存在しない新しいページを配置します。
ページエラー処理とシステムコール処理はほぼ同じで、コストも同じです。ユーザーモードプロセスを除いて、特別な指示は必要ありません。ほとんどの場合、ページフォルトがないため、速度が速くなります。
システムコールはtrap
命令(正確な命令はプロセッサ命令セットによって異なります)命令を使用します。trap
命令、ゼロ除算、割り込み、ページフォルト、その他のいくつかの点は同じ方法で処理されます。