A pager is a component or body of code that the VMM calls to move pages in and out of memory. Every committed page is associated with a pager except for hooked pages, instanced pages, and pages committed using _PageCommitPhys. Virtual devices can register pagers by using VMM services. Additional services enable virtual devices to immediately write pages to the swap file, or to discard pages that no longer contain valid information.
A pager is defined by a PD (pager descriptor) structure. This structure contains the addresses of pager functions. The VMM calls pager functions when a page needs be moved in or out of memory (paged in or out). The VMM calls other pager functions when it detects that a page has been accessed, and when a page is decommitted.
The VMM has four internal pagers that correspond to the following page types: fixed zero-initialized, swappable zero-initialized, fixed initialized, and swappable initialized. Fixed pages are paged in when committed, and are never paged out.
A virtual device can register a pager by using the _PagerRegister service. The VWIN32 device registers pagers to support memory mapped files. The service returns a handle that can be specified when pages are committed. To deregister a pager, use the _PagerDeregister service. To retrieve information about an existing pager, use the _PagerQuery service.
Registered pages that use MS-DOS functions to perform file operations must be able to do so during hardware interrupt processing. A file is identified by a file handle and a PSP. Any PSP created after Windows starts is instanced, and therefore may not be addressable by MS-DOS when a hardware interrupt occurs. Therefore, a virtual device must use the Get_PSP_Segment service to retrieve a PSP that is in global memory. It can then initialize the PSP with appropriate values and use nested execution services to call MS-DOS functions.
A virtual device can force a range of committed pages to be immediately paged out by using the _PageFlush service. This service calls the appropriate pager function to page out each page, but the pages remain present.
When referring to a page, the term "virgin" means that the page contents have never been altered. Virgin pages typically do not need to be paged out because they can always be regenerated, either by doing nothing (for uninitialized pages), zero-initialization (for zero-initialized pages), or by reading from a disk file (for demand-paged executables). The term "tainted" refers to a page whose contents have been altered. Tainted pages typically need to be saved to disk (either in the swap file or to a memory-mapped file) because their contents cannot be regenerated otherwise.
If the content of a range of pages is invalid or does not need to be preserved, you can discard the pages by using the _PageDiscardPages service. The pages remain committed, but are considered virgin pages. Therefore, they are not written to disk when they are next paged out, and are not read from disk when they are next paged in. Optionally, the pages can immediately be made not present.
See also Get_PSP_Segment, _PageDiscardPages, _PageFlush, _PagerDeregister, _PagerQuery, _PagerRegister, PD