The ExInitializePagedLookasideList routine initializes a lookaside list for pageable entries of the specified size.
VOID
ExInitializePagedLookasideList(
IN PPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate OPTIONAL,
IN PFREE_FUNCTION Free OPTIONAL,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth
);
PVOID
XxxAllocate (
IN POOL_TYPE PoolType, // PagedPool
IN SIZE_T NumberOfBytes, // value of Size
IN ULONG Tag // value of Tag
);
If the Allocate parameter is NULL, subsequent calls to ExAllocateFromPagedLookasideList automatically allocate entries whenever the lookaside list is empty.
VOID
XxxFree (
PVOID Buffer
);
If the Free parameter is NULL, subsequent calls to ExFreeToPagedLookasideList automatically release the given entry back to paged pool whenever the list is full, that is, currently holding the system-determined maximum number of entries.
None
Declared in wdm.h and ntddk.h. Include wdm.h or ntddk.h.
After calling ExInitializePagedLookasideList, blocks of the caller-specified Size can be allocated from and freed to the lookaside list with calls to ExAllocateFromPagedLookasideList and ExFreeToPagedLookasideList, respectively. Such dynamically allocated and freed entries can be any data structure or fixed-size buffer that the caller uses while the system is running, particularly if the caller cannot predetermine how many such entries will be in use at any given moment. The layout and contents of each fixed-size entry are caller-determined.
ExInitializePagedLookasideList initializes the system state to track usage of the given lookaside list, as follows:
The OS maintains a set of all lookaside lists in use. As demand for lookaside list entries and on available paged memory varies while the system runs, the OS adjusts its limits for the number of entries to be held in each paged lookaside list dynamically.
Drivers must always use explicitly free any lookaside lists they create before unloading. It is a serious programming error to do otherwise. Use ExDeleteNPagedLookasideList to free the list.
ExInitializePagedLookasideList sets up the opaque list head at the caller-supplied location but preallocates no memory for list entries. Subsequently, the initial entries are allocated dynamically as calls to ExAllocateFromPagedLookasideList occur, and these initial entries are held in the lookaside list as reciprocal calls to ExFreeToPagedLookasideList occur. Entries collect in the given lookaside list until the system-determined maximum is reached, whereupon any additional entries are returned to paged pool as they are freed. If the list becomes empty, allocate requests are satisfied by the XxxAllocate function specified at list initialization or by ExAllocatePoolWithTag.
It is more efficient to pass NULL pointers for the Allocate and Free parameters of ExInitializePagedLookasideList whenever the user of a lookaside list does nothing more than allocate and release fixed-size entries. However, any component that uses a lookaside list might supply these functions to do additional caller-determined processing, such as tracking its own dynamic memory usage by maintaining state about the number of entries it allocates and frees.
If the caller of ExInitializePagedLookasideList supplies an XxxAllocate function, that function must allocate entries for the lookaside list using the given input parameters when it calls ExAllocatePoolWithTag.
Callers of ExInitializePagedLookasideList must be running at IRQL < DISPATCH_LEVEL.
ExAllocateFromPagedLookasideList, ExAllocatePoolWithTag, ExDeletePagedLookasideList, ExFreePool, ExFreeToPagedLookasideList, ExInitializeNPagedLookasideList