ExInitializeLo以sideListEx 函式 (wdm.h)
ExInitializeLo一sideListEx 例程會初始化 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 專案。 如果 lookaside 清單是空的 (不包含) 任何專案, ExAllocateFromLo一sideListEx 例程會呼叫 這個 LookasideListAllocateEx 例程。 此參數是選擇性的,如果不需要自定義配置例程,則可以指定為 NULL 。 如果此參數為 NULL,則呼叫 ExAllocateFromPagedLo以SideList 自動配置分頁或非分頁記憶體 (,如新專案的 PoolType 參數所決定) 。
[in, optional] Free
呼叫端提供的 LookasideListFreeEx 例程指標,釋放先前配置的 lookaside-list 專案。 如果 lookaside 列表已滿 (, 則 ExFreeToPagedLo一sideList 例程會呼叫 這個 LookasideListFreeEx 例程,也就是清單已經包含操作系統) 所決定的最大專案數目。 此參數是選擇性的,如果不需要自定義解除分配例程,則可以指定為 NULL 。 如果此參數為 NULL,則呼叫 ExFreeToPagedLo一sideList 會自動釋放指定專案的記憶體。
[in] PoolType
指定 lookaside 清單中的專案集區類型。 將此參數設定為有效的 POOL_TYPE 列舉值。
[in] Flags
指定選擇性旗標值,以修改 LookasideListAllocateEx 例程的預設行為。 將此參數設定為零或設定為下列其中一個 EX_LOOKASIDE_LIST_EX_FLAGS_XXX 旗標位。
旗標位 | Description |
---|---|
EX_LOOKASIDE_LIST_EX_FLAGS_RAISE_ON_FAIL | 如果配置失敗,請引發例外狀況。 |
EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE | 如果配置失敗,請傳回 NULL ,而不是引發例外狀況。 此旗標適用於配置例程,例如 ExAllocatePoolWithQuotaTag,以收取集區使用量配額的費用。 |
這兩個旗標位互斥。
如果 Allocate 為 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 參數值會以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 參數值會以POOL_QUOTA_FAIL_INSTEAD_OF_RAISE旗標位位來形成傳遞至 LookasideListAllocateEx 例程的 PoolType 參數值。 LookasideListAllocateEx 例程可以將此 PoolType 值傳遞至 ExAllocatePoolWithQuotaTag 例程。 如需POOL_QUOTA_FAIL_INSTEAD_OF_RAISE旗標的詳細資訊,請參閱 ExAllocatePoolWithQuotaTag。
[in] Size
指定 lookaside 列表中每個專案的大小,以位元組為單位。
[in] Tag
指定四位元組集區標籤,用來標記所配置記憶體以供 lookaside-list 專案使用。 如需集區標籤的詳細資訊,請參閱 ExAllocatePoolWithTag 中的 Tag 參數描述。
[in] Depth
保留的。 一律將此參數設定為零。
傳回值
如果呼叫成功,ExInitializeLo一sideListEx 會傳回STATUS_SUCCESS。 可能的傳回值包括下列錯誤碼:
傳回碼 | Description |
---|---|
STATUS_INVALID_PARAMETER_4 | PoolType 參數值無效。 |
STATUS_INVALID_PARAMETER_5 | Flags 參數值無效。 |
備註
驅動程式必須呼叫此例程,才能開始使用清單,以初始化 lookaside 清單。 lookaside 清單是固定大小的緩衝區集區,驅動程式可以在本機管理以減少系統配置例程的呼叫數目,進而改善效能。 緩衝區會儲存為 lookaside 清單中的專案。 清單中的所有專案都是相同的統一大小,由 Size 參數指定。
在 ExInitializeLo以sideListEx 傳回之後,會初始化 lookaside 清單,但不包含任何專案。 當用戶端呼叫 ExAllocateFromLo以清單Ex 例程來要求專案時,此例程會判斷 lookaside 清單是空的,並呼叫驅動程式提供的 LookasideListAllocateEx 例程,以動態配置新項目的記憶體。 可能會配置其他專案,以回應來自客戶端的類似要求。 稍後,當用戶端呼叫 ExFreeToLo 以ListEx 釋放這些專案時,此例程會將專案插入 lookaside 清單中。 如果清單中的項目數目達到操作系統所決定的限制, ExFreeToLo在ListEx 停止將進一步的專案新增至清單,而是將這些專案傳遞給驅動程式提供的 LookasideListFreeEx 例程以釋放。
如果驅動程式未提供 LookasideListAllocateEx 和 LookasideListFreeEx 例程,則 ExAllocateFromLomountsideListEx 和 ExFreeToLomountsideListEx 例程會改用預設配置和解除分配例程。
提供 LookasideListAllocateEx 和 LookasideListFreeEx 例程沒有任何好處,但不會呼叫 ExAllocatePoolWithTag 和 ExFreePool。 只要將 [配置 ] 和 [ 免費 ] 參數設定為 NULL,即可達到相同的效能。
在驅動程式卸除之前,它必須明確釋放它所建立的任何外觀清單。 無法這麼做是嚴重的程序設計錯誤。 呼叫 ExListEx 例程以釋出 lookaside 清單。 這個例程會釋放指定 lookaside 清單中任何剩餘專案的儲存空間,然後從整個系統的作用中 lookaside 清單中移除清單。
操作系統會持續追蹤目前正在使用的所有外觀清單。 由於可用的非分頁記憶體數量和 lookaside 清單專案的需求會隨著時間而有所不同,操作系統會動態調整其每個非分頁 lookaside 清單中項目數目上限的限制。
在 Windows 2000 和更新版本中,包含分頁或非分頁項目的外觀清單可以分別由 PAGED_LOOKASIDE_LIST 或 NPAGED_LOOKASIDE_LIST 結構來描述。
如需 lookaside 列表的詳細資訊,請參閱使用 Lookaside 清單。
ExInitializeLo一sideListEx 的呼叫端可以在 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 參數來存取私人數據。
在此範例中的 MyLomountsideListAllocateEx 例程傳回之後, ExAllocateFromLo一sideListEx 會將 NewEntry 變數指向的緩衝區插入 lookaside 列表中。 為了讓此插入作業安全線程, ExAllocateFromLo一sideListEx 會同步處理其 lookaside 清單的存取權,以及其他線程可能執行的其他清單插入和移除作業。 同樣地,當 ExFreeFromLo一sideListEx 從 lookaside 清單中移除緩衝區時,它會同步處理清單的存取權。
ExAllocateFromLo以列表ListEx 和 ExFreeFromLo,sideListEx 不會同步其呼叫驅動程式提供的 LookasideListAllocateEx 和 LookasideListFreeEx 例程。 因此,如果上述程式代碼範例中的 MyLo,sideListAllocateEx 和 MyLo一sideListFreeEx 例程必須是安全線程,驅動程式必須提供必要的同步處理。
範例例程 MyLo以ListAllocateEx 同步處理其 MyContext-NumberOfAllocations> 變數的存取權,以及其他可能會遞增和遞減此變數的線程。 為了提供此同步處理, MyLo一sideListAllocateEx 會呼叫 InterlockedIncrement 例程,以不可部分完成遞增此變數。 同樣地,) 未顯示 MyLo可sideListFreeEx 例程 (呼叫 InterlockedDecrement 例程,以不可部分完成遞減此變數。
不過,如果上述程式代碼範例中 MyContext-NumberOfAllocations> 變數的唯一用途只是收集查閱清單配置的統計數據,則很難有不可部分完成的遞增和遞減。 在此情況下,遺漏遞增或遞減的遠端可能性不應該是問題。
如需 lookaside 清單線程安全性的詳細資訊,請參閱使用 Lookaside 清單。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | 從 Windows Vista 開始提供。 |
目標平台 | Universal |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL (请参阅一节) |