ExInitializeLookasideListEx 函式 (wdm.h)
ExInitializeLookasideListEx 例程會初始化 lookaside 清單。
語法
NTSTATUS ExInitializeLookasideListEx(
[out] PLOOKASIDE_LIST_EX Lookaside,
[in, optional] PALLOCATE_FUNCTION_EX Allocate,
[in, optional] PFREE_FUNCTION_EX Free,
[in] POOL_TYPE PoolType,
[in] ULONG Flags,
[in] SIZE_T Size,
[in] ULONG Tag,
[in] USHORT Depth
);
參數
[out] Lookaside
要初始化之 LOOKASIDE_LIST_EX 結構的指標。 傳回時,此結構描述空的 lookaside 清單。 不論 lookaside 清單中的專案是從分頁或非分頁記憶體配置,呼叫端都必須針對這個結構使用非分頁系統空間。 在64位平臺上,此結構必須對齊16位元組。
[in, optional] Allocate
呼叫端提供的 LookasideListAllocateEx 例程的指標,該例程會配置新的 lookaside-list 專案。 ExAllocateFromLookasideListEx 例程會呼叫此 LookasideListAllocateEx 例程,如果 lookaside 列表是空的(不包含任何專案)。 此參數是選擇性的,如果不需要自定義配置例程,則可以指定為 null 。 如果此參數 NULL,則呼叫 ExAllocateFromPagedLookasideList 會自動為新專案配置分頁或非分頁記憶體(由 PoolType 參數決定)。
[in, optional] Free
呼叫端提供的指標 LookasideListFreeEx 例程,釋放先前配置的 lookaside 清單專案。 如果 lookaside 列表已滿,ExFreeToPagedLookasideList 例程會呼叫此 LookasideListFreeEx 例程(也就是列表已經包含作系統所決定的項目數上限)。 此參數是選擇性的,如果不需要自定義解除分配例程,則可以指定為 NULL。 如果此參數 NULL,則呼叫 ExFreeToPagedLookasideList 會自動釋放指定專案的記憶體。
[in] PoolType
指定 lookaside 清單中專案的集區類型。 將此參數設定為有效的 POOL_TYPE 列舉值。
[in] Flags
指定選擇性旗標值,以修改 LookasideListAllocateEx 例程的默認行為。 將此參數設定為零或設定為下列其中一個EX_LOOKASIDE_LIST_EX_FLAGS_XXX 旗標位。
旗標位 | 描述 |
---|---|
EX_LOOKASIDE_LIST_EX_FLAGS_RAISE_ON_FAIL | 如果配置失敗,請引發例外狀況。 |
EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE | 如果配置失敗,請傳回 NULL,而不是引發例外狀況。 此旗標適用於與配置例程搭配使用,例如 ExAllocatePoolWithQuotaTag,以收取集區使用量配額的費用。 |
這兩個旗標位互斥。
如果 配置 為 NULL ,請將 Flags 設為零或EX_LOOKASIDE_LIST_EX_FLAGS_RAISE_ON_FAIL,但不要設定為 EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE。 否則,預設配置例程的行為是未定義的。
如果 Flags = EX_LOOKASIDE_LIST_EX_FLAGS_RAISE_ON_FAIL,則 PoolType 參數值是位 ORed,具有POOL_RAISE_IF_ALLOCATION_FAILURE旗標位,以形成傳遞 至 LookasideListAllocateEx 例程的 PoolType 參數值。 LookasideListAllocateEx 例程可以傳遞這個 PoolType 值,而不需修改,即可將 ExAllocatePoolWithTag 例程傳遞。 如需POOL_RAISE_IF_ALLOCATION_FAILURE旗標的詳細資訊,請參閱 ExAllocatePoolWithTag。
如果 Flags = EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE,PoolType 參數值會是位 ORed,其具有POOL_QUOTA_FAIL_INSTEAD_OF_RAISE旗標位,以形成傳遞 至 lookasideListAllocateEx 例程的 PoolType 參數值。 LookasideListAllocateEx 例程可以傳遞這個 PoolType 值,而不需修改,即可將 ExAllocatePoolWithQuotaTag 例程傳遞。 如需POOL_QUOTA_FAIL_INSTEAD_OF_RAISE旗標的詳細資訊,請參閱 ExAllocatePoolWithQuotaTag。
[in] Size
指定 lookaside 列表中每個專案的大小,以位元組為單位。
[in] Tag
指定要用來標記所配置記憶體的四位元組集區標記,以用於尋找清單專案。 如需集區卷標的詳細資訊,請參閱 ExAllocatePoolWithTag中 Tag 參數的描述。
[in] Depth
保留。 一律將此參數設定為零。
傳回值
如果呼叫成功,ExInitializeLookasideListEx 會傳回STATUS_SUCCESS。 可能的傳回值包括下列錯誤碼:
傳回碼 | 描述 |
---|---|
STATUS_INVALID_PARAMETER_4 | PoolType 參數值無效。 |
STATUS_INVALID_PARAMETER_5 | Flags 參數值無效。 |
言論
驅動程式必須呼叫此例程來初始化 lookaside 清單,才能開始使用清單。 外觀清單是固定大小的緩衝區集區,驅動程式可以在本機管理,以減少系統配置例程的呼叫數目,進而改善效能。 緩衝區會儲存為 lookaside 清單中的專案。 清單中的所有專案都是相同的統一大小,由 Size 參數指定。
ExInitializeLookasideListEx 傳回之後,會初始化 lookaside 清單,但不包含任何專案。 當用戶端呼叫 ExAllocateFromLookasideListEx 例程來要求專案時,此例程會判斷 lookaside 清單是空的,並呼叫驅動程式提供的 LookasideListAllocateEx 例程,以動態配置新項目的記憶體。 可能會配置其他專案,以回應來自客戶端的類似要求。 稍後,當用戶端呼叫 ExFreeToLookasideListEx 以釋放這些專案時,此例程會將專案插入 lookaside 列表中。 如果清單中的項目數達到作系統所決定的限制,ExFreeToLookasideListEx 停止將其他專案新增至清單,而是將這些專案傳遞至驅動程式提供的 LookasideListFreeEx 例程。
如果驅動程式不提供 lookasideListAllocateEx 和 LookasideListFreeEx 例程,ExAllocateFromLookasideListEx 和 ExFreeToLookasideListEx 例程會改用預設配置和解除分配例程。
提供 lookasideListAllocateEx 和 LookasideListFreeEx 例程沒有 好處,只呼叫 exAllocatePoolWithTag ExAllocatePoolWithTag,ExFreePool。 只要將 [配置] 和 [免費 參數設定 為 NULL,即可以更好的效能達到相同的效果。
在驅動程式卸除之前,它必須明確釋放它建立的任何外觀清單。 無法這樣做是嚴重的程序設計錯誤。 呼叫 ExDeleteLookasideListEx 例程以釋放 lookaside 清單。 此例程會釋放指定之 lookaside 清單中任何剩餘專案的儲存空間,然後將清單從整個系統的作用中查閱清單中移除。
作系統會追蹤目前正在使用的所有外觀清單。 由於可用的非分頁記憶體數量和對 lookaside 清單專案的需求隨著時間而有所不同,作系統會動態調整其每個非分頁查閱清單項目數目上限的限制。
在 Windows 2000 和更新版本的 Windows 中,可分別以 PAGED_LOOKASIDE_LIST 或 NPAGED_LOOKASIDE_LIST 結構描述包含分頁或非分頁專案的外觀清單。
如需 lookaside 列表的詳細資訊,請參閱使用 Lookaside 清單 。
ExInitializeLookasideListEx 的呼叫者可以在 IRQL <= DISPATCH_LEVEL執行,但通常會在 IRQL = PASSIVE_LEVEL執行。
例子
驅動程式提供的 LookasideListAllocateEx 和 LookasideListFreeEx 例程都會接收指向描述 lookaside 清單之 LOOKASIDE_LIST_EX 結構的 lookaside 參數。 例程可以使用此參數來存取驅動程式與 lookaside 列表相關聯的私人數據。 例如,驅動程式可能會配置下列結構的實例,以針對它所建立的每個 lookaside 清單收集私人數據:
typedef struct
{
ULONG NumberOfAllocations; // number of entries allocated
ULONG NumberOfFrees; // number of entries freed
LOOKASIDE_LIST_EX LookasideField;
} MY_PRIVATE_DATA;
驅動程式可以初始化 lookaside 清單,如下列程式代碼範例所示:
#define ENTRY_SIZE 256
#define MY_POOL_TAG 'tsLL'
MY_PRIVATE_DATA *MyContext;
NTSTATUS status = STATUS_SUCCESS;
MyContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(MY_PRIVATE_DATA), MY_POOL_TAG);
if (MyContext)
{
MyContext.NumberOfAllocations = 0;
MyContext.NumberOfFrees = 0;
status = ExInitializeLookasideListEx(
&MyContext.LookasideField,
MyLookasideListAllocateEx,
MyLookasideListFreeEx,
NonPagedPool,
0,
ENTRY_SIZE,
MY_POOL_TAG,
0);
}
else
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
下列程式代碼範例示範 lookasideListAllocateEx 例程如何使用其 Lookaside 參數來存取與 lookaside 列表相關聯的私人數據:
PVOID
MyLookasideListAllocateEx(
__in POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes,
__in ULONG Tag,
__inout PLOOKASIDE_LIST_EX Lookaside)
{
MY_PRIVATE_DATA *MyContext;
PVOID NewEntry;
MyContext = CONTAINING_RECORD(Lookaside, MY_PRIVATE_DATA, LookasideField);
NewEntry = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
if (NewEntry)
{
ULONG NumberOfAllocations = (ULONG) InterlockedIncrement((LONG volatile*)&MyContext->NumberOfAllocations);
}
return NewEntry;
}
CONTAINING_RECORD 巨集定義於 Ntdef.h 頭檔中。 LookAsideListFreeEx 例程同樣可以使用其 Lookaside 參數來存取私人數據。
在此範例中 MyLookasideListAllocateEx 例程傳回之後,ExAllocateFromLookasideListEx 將 NewEntry 變數指向的緩衝區插入 lookaside 列表中。 若要讓此插入作業安全線程,ExAllocateFromLookasideListEx 會同步處理其查閱清單的存取權,以及其他線程可能執行的其他清單插入和移除作業。 同樣地,ExFreeFromLookasideListEx 從 lookaside 列表中移除緩衝區時,它會同步處理其清單的存取權。
ExAllocateFromLookasideListEx 和 ExFreeFromLookasideListEx 不會同步處理其呼叫至驅動程式提供的 LookasideListAllocateEx 和 LookasideListFreeEx 例程。 因此,如果上述程式代碼範例中的 MyLookasideListAllocateEx 和 MyLookasideListFreeEx 例程必須是安全線程,驅動程式必須提供必要的同步處理。
範例例程 MyLookasideListAllocateEx,會同步處理其存取 MyContext->NumberOfAllocations 變數與其他可能遞增和遞減此變數的線程。 若要提供此同步處理,MyLookasideListAllocateEx 會呼叫 InterlockedIncrement 例程,以不可部分完成地遞增此變數。 同樣地,MyLookasideListFreeEx 例程(未顯示)可以呼叫 InterlockedDecrement 例程,以不可部分完成遞減此變數。
不過,如果上述程式代碼範例中 MyContext->NumberOfAllocations 變數的唯一用途只是為了收集查閱清單配置上的統計數據,則幾乎不需要不可部分完成的遞增和遞減。 在此情況下,遺漏遞增或遞減的遠端可能性不應該是問題。
如需 lookaside 列表線程安全性的詳細資訊,請參閱使用 Lookaside 清單 。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | 從 Windows Vista 開始提供。 |
目標平臺 | 普遍 |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
連結庫 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL (請參閱一節) |