Default Pager
Default Pagerは補助記憶装置へのPageOut/PageInを行う。
Default Pagerには管理用の構造体としてvstructがある。vstructとvm_objectとの関係を図1に示す。vm_objectのpagerが指すmemory_objectのpager値がISVSの値だとmemory_objectはvstructであることを意味する(vstructの先頭4Byteはmemory_objectと共有する)。
このマップからVM Objectが示すRegionの先頭からのオフセットからクラスタ番号を求めvsmapを取得すると対応するPageing Segment(ページアウトされているデバイスやファイル)を取得できる。
vsmap_psindexにはPaging Segmentへのポインタが入っており、これはPageOut時に設定される。PageInの時はこのvsmapに登録された情報にしたがってデータを読み込む。
各Paging Segmentは各Segmentの空き容量を管理する。ps_pgnumが総ページ数でps_clcountが実際の空き容量となる(クラスタ数。ps_clshiftだけ右シフトするとページ数になる)。
Paging Segmentはdefault_pager_add_file(), default_pager_add_segment()によって作成される。default_pager_add_file()はスワップファイルをPagerに登録するルーチンでmacx_swapon()から呼ばれる。default_pager_add_segment()はスワップパーティションをPagerに登録するルーチン。
[関連関数]
dp_memory_object_data_request()
dp_memory_object_data_return()
pvs_cluster_read(vs, vs_offset, cnt)
vs_cluster_write()
Default Pagerには管理用の構造体としてvstructがある。vstructとvm_objectとの関係を図1に示す。vm_objectのpagerが指すmemory_objectのpager値がISVSの値だとmemory_objectはvstructであることを意味する(vstructの先頭4Byteはmemory_objectと共有する)。
図1 vstruct
表1 vstructの内容(一部)
フィールド | 内容 |
---|---|
vs_mem_obj | memory_objectとの共用部分。ISVS(123456)の値が入っているはず。 |
vs_control | memory_object_controlへのポインタ。ここ経由でvm_objectへ遡ることができる。 |
vs_readers | 処理中のReadRequest数 |
vs_writers | 処理中のWriteRequest数 |
vs_indirect | クラスタマップがIndirectマップ。(vsu_imapが有効) |
vsu_dmap | クラスタのDirectマップ(vs_indirect == FALSEの時有効) |
vsu_imap | クラスタのInirectマップ(vs_indirect == TRUEの時有効) |
vsmap
VM Object内のクラスタ(PageIn/Outはクラスタ単位で行われる)のデータがどこに補助記憶装置のどこに置かれているかを調べるためにvsmapがある。VM Objectのサイズが小さい時は、vstructのvs_dmapにDirectマップが構築され、サイズが大きくなるとvs_imapにIndirectマップが構築される。クラスタ毎にvsmapが1エントリ存在する。図2参照。このマップからVM Objectが示すRegionの先頭からのオフセットからクラスタ番号を求めvsmapを取得すると対応するPageing Segment(ページアウトされているデバイスやファイル)を取得できる。
vsmap_psindexにはPaging Segmentへのポインタが入っており、これはPageOut時に設定される。PageInの時はこのvsmapに登録された情報にしたがってデータを読み込む。
図2 vsmap
Paging Segment
仮想記憶を行う上でページアウトするデバイス、パーティション毎にPaging Segmentが作成されて管理される。Paging Segmentはpaging_segments[]からまとめて管理される(図3)。各Paging Segmentは各Segmentの空き容量を管理する。ps_pgnumが総ページ数でps_clcountが実際の空き容量となる(クラスタ数。ps_clshiftだけ右シフトするとページ数になる)。
Paging Segmentはdefault_pager_add_file(), default_pager_add_segment()によって作成される。default_pager_add_file()はスワップファイルをPagerに登録するルーチンでmacx_swapon()から呼ばれる。default_pager_add_segment()はスワップパーティションをPagerに登録するルーチン。
図3 Paging Segment
[関連関数]
dp_memory_object_data_request()
PageIn処理を行うDefault Pagerのエントリルーチン。
dp_memory_object_data_return()
PageOut処理を行うDefault Pagerのエントリルーチン。
default_pager_memory_object_create()vstructを構築する。
vm_object_pager_create()でVM ObjectにDefault
Pagerを割り当てる時に使われる。Default PagerはVM
Objectが作成された時には作られず、PageOut時にはじめて作成される。
pvs_cluster_read(vs, vs_offset, cnt)
クラスタの読み込み処理
UPLを作成してps_read_file()に処理を渡す。
最終的にはBSD側に実装されているPageIn処理(vnode_pagein())へ。
vs_cluster_write()
クラスタの書き込み処理
CL_FIND無しでps_clmap()を呼び出すことで該当vsmapにまだPaging
Segmentが割り当てられていなかった場合は、新たに割り当てる。どのPaging
Segmentを選ぶかはps_select_segment()で決めているみたい。