A "sparse memory" block is a range of linear addresses in which not all pages are necessarily available for use. The owner of a sparse memory block is responsible for making pages available ("committing") and removing pages ("decommitting"), as it sees fit. Accessing a page which is not committed will raise a protection exception. The sparse memory functions allow a VxD to manage linear address space in roughly the same way as the Win32 "VirtualAlloc" and related functions.
Sparse memory allocation services allocate pages in two steps. First, you reserve a range of pages; then you commit pages as they are needed. Reserving pages sets the corresponding linear addresses aside for a specific purpose, but does not consume any physical storage. Committing pages allocates physical storage for them. Free pages are those that are neither reserved nor committed.
Suppose a virtual device uses a data structure that must be contiguous and that varies in size over time. By reserving a large range of pages, and committing them as needed, the virtual device can efficiently grow the data structure. Because the reserved pages are guaranteed to be available, growing the structure never requires copying it to a new location.
To reserve a range of pages, use the _PageReserve service. Collectively, the pages reserved in a single call to the _PageReserve service comprise a memory block. The base linear address returned by _PageReserve identifies the block. For example, you specify this address when you free the block using the _PageFree service.
To commit pages, use the _PageCommit service. This service allocates physical storage for a range of pages, and enables you to specify whether the pages are fixed (permanently locked) and what their privileges are. (Committing pages fixed rather than locked is more efficient if your VxD will never unlock the pages.) All pages committed at one time must be in the same memory block — that is, they must have been reserved by a single call to the _PageReserve service. To decommit pages, use the _PageDecommit service. Decommitting pages is different from freeing a memory block because the pages remain reserved.
The _PageCommit service allocates physical memory purely on the basis of availability, such that there is no correlation between linear and physical addresses. Virtual device may sometimes require pages to be physically contiguous — for example, when allocating a DMA buffer. Using the _PageCommitContig service, you can commit pages that are physically contiguous, and may also specify a physical alignment and a range of allowable physical addresses.
The _PageCommitPhys service maps a range of pages to the specified physical addresses. The pages are considered committed. However, no physical memory is allocated by this service. That is, the service does not verify that the specified physical addresses are available, and not does update the list of free physical pages. The specified physical addresses must be outside the control of the memory manager, or otherwise under the control of the virtual device. For more information about the memory manager's use of physical memory, see Free Physical Page Management.
_PageCommit, _PageCommitContig, _PageCommitPhys, _PageDecommit, _PageFree, _PageReserve