[[PageNavi(internal22-navi)]]
{{{ comment
h2w-title:空間の複製
}}}
= 空間の複製 = #SECTION04340000000000000000
仮想空間の複製はdup_mmap関数にて行う. この関数はforkシステムコールでのみ利用される.
この関数では、仮想空間の複製のみを行うが、物理メモリの複製は行わず二つの空間で共有させる。物理メモリの複製はどちらかの仮想空間に対し、書きこみがあるまで遅延させる。
その実現のため、二つの仮想空間のPTEにおいて書きこみ禁止モード(コピーオンライトモード)にしておく。書きこみ禁止であっても、この空間に対する読み込み処理は可能である。
{{{
dup_mmap(メモリ管理構造体mm_struct)
{
for (カレントプロセスのmm_structに登録されている全ての仮想空間管理構造体vm_area_structに対して) {
新しい仮想空間管理構造体vm_area_structを確保
カレントの仮想空間管理構造体vm_area_structの情報を、
新しい仮想空間管理構造体vm_area_structにコピー
新しい仮想空間管理構造体vm_area_structを、引数で渡された
メモリ管理構造体mm_structに登録
if(ファイルマップされた仮想空間域なら) {
一つのファイルを共有しているしていることを管理する
ため、仮想空間管理構造体をvm_area_struct相互にリンクしておく
}
PGD,PTEをコピー(copy_page_range関数)
}
}
}}}
この関数ではPTEのみのコピーのみをおこない、ページの実体コピーは行わない。空間が個別マップで、かつ書きこみ可能ならコピーオンライトモードでマップする.
{{{
copy_page_range(コピー先メモリ管理構造体vm_area_struct、
コピー元メモリ管理構造体vm_area_struct、 仮想空間管理構造体)
{
コピー元の先頭PGDを求める(pgd_offset関数)
コピー先の先頭PGDを求める(pgd_offset関数)
for(仮想空間のある間、全てのコピー元PGDに対し) {
if (コピー元のPGDが空)continue
if (コピー先のPGDが空)
PMDテーブルを確保、登録(pmd_alloc関数)
コピー元のPGDが指す先頭PMDを求める(pmd_offset関数)
コピー先のPGDが指すPMDを求める(pmd_offset関数)
for(コピー元PGD内の全てのPMDに対し) {
if (コピー元のPMDが空)continue
if (コピー先のPMDが空)
PTEテーブルを確保、登録(pte_alloc関数)
コピー元のPMDが指す先頭PTEを求める(pte_offset関数)
コピー先のPMDが指すPTEを求める(pte_offset関数)
for(コピー元PGD内の全てのPTEに対し) {
if (コピー元のPTEが空)continue
if (PTEが有効でない(!pte_present関数) ) {
スワップ参照数を1増やす
(swap_duplicate関数)
コピー元のPTEの内容をコピー先のPTEに
複製(set_pte関数)
contnue
}
if (個別マップ、かつ書きこみ可能の空間) {
コピー元のPTEの書き込み可のビットを
落とし(pte_wrprotect関数)、コピー元の
PTEに下記戻しておく(set_pte関数)
}
if (共有モードでの複製なら) {
PTEからdirtyビットを落とす(pte_mkclean関数)
}
PTEにアクセスビットを立てる(pte_mkclean関数)
コピー先のPTEにコピー(set_pte関数)
}
}
}
}
}}}
下図のように、書き込み可能なページをマップするPTEも全て、書き込み不可(Wビットオフ)としてマップし直す。
[[Embed(internal22-images:img64.gif)]]
----
''(NIS)HirokazuTakahashi [[BR]]2000年06月11日 (日) 22時29分57秒 JST''1
[[PageNavi(internal22-navi)]]