共用方式為


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,以收取集區使用量配額的費用。

這兩個旗標位互斥。

如果 AllocateNULL,請將 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 例程以釋放。

如果驅動程式未提供 LookasideListAllocateExLookasideListFreeEx 例程,則 ExAllocateFromLomountsideListEx 和 ExFreeToLomountsideListEx 例程會改用預設配置和解除分配例程。

提供 LookasideListAllocateExLookasideListFreeEx 例程沒有任何好處,但不會呼叫 ExAllocatePoolWithTagExFreePool。 只要將 [配置 ] 和 [ 免費 ] 參數設定為 NULL,即可達到相同的效能。

在驅動程式卸除之前,它必須明確釋放它所建立的任何外觀清單。 無法這麼做是嚴重的程序設計錯誤。 呼叫 ExListEx 例程以釋出 lookaside 清單。 這個例程會釋放指定 lookaside 清單中任何剩餘專案的儲存空間,然後從整個系統的作用中 lookaside 清單中移除清單。

操作系統會持續追蹤目前正在使用的所有外觀清單。 由於可用的非分頁記憶體數量和 lookaside 清單專案的需求會隨著時間而有所不同,操作系統會動態調整其每個非分頁 lookaside 清單中項目數目上限的限制。

在 Windows 2000 和更新版本中,包含分頁或非分頁項目的外觀清單可以分別由 PAGED_LOOKASIDE_LISTNPAGED_LOOKASIDE_LIST 結構來描述。

如需 lookaside 列表的詳細資訊,請參閱使用 Lookaside 清單

ExInitializeLo一sideListEx 的呼叫端可以在 IRQL = DISPATCH_LEVEL執行,但通常會在 IRQL <= PASSIVE_LEVEL執行。

範例

驅動程式提供的 LookasideListAllocateExLookasideListFreeEx 例程都會收到 指向描述 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以列表ListExExFreeFromLo,sideListEx 不會同步其呼叫驅動程式提供的 LookasideListAllocateExLookasideListFreeEx 例程。 因此,如果上述程式代碼範例中的 MyLo,sideListAllocateExMyLo一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 (请参阅一节)

另請參閱

ExAllocateFromLookasideListEx

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTag

ExDeleteLookasideListEx

ExFreePool

ExFreeToLofreesideListEx

InterlockedDecrement

InterlockedIncrement

LOOKASIDE_LIST_EX

LookasideListAllocateEx

LookasideListFreeEx

NPAGED_LOOKASIDE_LIST

PAGED_LOOKASIDE_LIST

POOL_TYPE