必須動態配置固定大小的緩衝區以執行隨選 I/O 作業的驅動程式可以使用 ExXxxLookasideListEx 或 ExXxxLookasideList 支援例程。 在這類驅動程式初始化其 lookaside 清單之後,操作系統會在驅動程式的 lookaside 清單中,保留若干個配置為指定大小的動態緩衝區,從而有效地為驅動程式保留一組可重複使用的固定大小緩衝區。 驅動程序在預留清單中的固定大小緩衝區(也稱為 專案)的格式和內容由其自行決定。
例如,必須設定 SCSI 要求區塊(SRB)供基礎 SCSI 埠/迷你埠驅動程式使用的儲存類驅動程式會使用前瞻清單。 這類驅動程式會根據需要從其 lookaside 清單配置 SRB 緩衝區,並在每次 SRB 傳回由類驅動程式完成的 IRP 時,將每個 SRB 緩衝區釋放回 lookaside 清單以供重複使用。 因為儲存類別驅動程式無法預先確定在任何時間點需要使用多少個 SRB,因為驅動程式的 I/O 需求可能會增加或減少,因此使用旁路清單來管理這類驅動程式中固定大小 SRB 的緩衝區配置和釋放是一種方便且經濟的方法。
操作系統會針對目前正在使用的所有分頁和非分頁旁路清單,動態地追蹤所有清單中專案配置和解除配置的需求,以及可用於新專案的系統集區。 當配置需求很高時,作業系統會增加它在每個旁視清單中保留的項目數目。 當需求再次下降時,將多餘的旁路項目釋放回系統集區。
Lookaside 清單是執行緒安全的。 Lookaside 清單具有內建同步處理功能,可讓驅動程式中多個同時執行的線程共用 Lookaside 清單。 這些線程可以從共用外觀清單安全地配置緩衝區,並將這些緩衝區釋放到清單中,而不需要驅動程序明確地同步處理這些作業。 不過,為了避免可能的外泄和數據損毀,共用查閱清單的一組線程必須明確同步處理清單的初始化和刪除。
Lookaside 清單介面
從 Windows Vista 開始, LOOKASIDE_LIST_EX 結構描述可包含分頁或非分頁緩衝區的查閱清單。 如果驅動程式為此旁路清單提供自訂的 分配 和 釋放 程序,這些程序會以輸入參數的形式接收私用上下文。 驅動程式可以使用此內容來收集 lookaside 列表的隱私資料。 例如,上下文可用來計算列表中動態配置和釋放的條目數量。 如需示範如何以這種方式使用上下文的程式範例,請參閱 ExInitializeLookasideListEx。
下列系統提供的例程支援下列由 LOOKASIDE_LIST_EX 結構描述的 lookaside 清單:
從 Windows 2000 開始,PAGED_LOOKASIDE_LIST 結構描述包含分頁緩衝區的旁視列表。 如果驅動程式為此 Lookaside 清單提供自定義的 Allocate 和 Free 例程,這些例程不會接收作為輸入參數的私有上下文。 因此,如果您的驅動程式只打算在 Windows Vista 和 Windows 更新版本上執行,請考慮使用 LOOKASIDE_LIST_EX 結構,而非使用 PAGED_LOOKASIDE_LIST 結構來管理您的轉向列表。 下列由系統提供的例程支援由 PAGED_LOOKASIDE_LIST 結構描述的 lookaside 清單:
ExAllocateFromPagedLookasideList
ExInitializePagedLookasideList
從 Windows 2000 開始,NPAGED_LOOKASIDE_LIST 結構描述了一個包含非分頁的緩衝區的查閱清單。 如果驅動程式為此旁路清單提供自定義的 Allocate 和 Free 例程,則這些例程不會以輸入參數的形式接收私用內容。 同樣地,如果您的驅動程式只打算在 Windows Vista 和更新版本的 Windows 上執行,請考慮使用 LOOKASIDE_LIST_EX 結構,而不是 NPAGED_LOOKASIDE_LIST 結構來建立旁視清單。 下列系統提供的例程支援 NPAGED_LOOKASIDE_LIST 結構所描述的 lookaside 清單:
ExAllocateFromNPagedLookasideList
ExInitializeNPagedLookasideList
實作指導方針
若要實作使用 LOOKASIDE_LIST_EX 結構的旁觀表,請遵循下列設計指南:
調用 ExInitializeLookasideListEx 以配置 lookaside 列表。 在此呼叫中,設定 "lookaside" 清單中的項目是要分頁或非分頁緩衝區。 如果驅動程式本身或任何接收其預留清單條目的基礎驅動程式可能會在 IRQL >= DISPATCH_LEVEL 訪問這些條目,請使用非分頁緩衝區。 只有當存取驅動程式的旁置列表項目時總是在 IRQL <= APC_LEVEL,才使用分頁緩衝區。
不論清單中的專案是分頁還是非分頁,lookaside 清單的 LOOKASIDE_LIST_EX 結構都必須始終存放在非分頁的系統記憶體中。
為了獲得更好的效能,除非配置和解除分配例程必須只針對 lookaside 列表專案進行配置和釋放,否則將 Allocate 和 Free 參數的 NULL 指標傳遞至 ExInitializeLookasideListEx。 例如,這些例程可能會記錄驅動程式使用動態配置緩衝區的相關信息。
驅動程式提供的 Allocate 例程可以將它直接接收的輸入參數 (PoolType、Tag 和 Size) 傳遞至 ExAllocatePoolWithTag 或 ExAllocatePoolWithQuotaTag 例程來配置新的緩衝區。
針對每次呼叫 ExAllocateFromLookasideListEx,在先前分配的項目已不再使用時,應儘快呼叫 ExFreeToLookasideListEx。
提供只呼叫 ExAllocatePoolWithTag 和 ExFreePool 的 Allocate 和 Free 例程,分別浪費處理器週期。 ExAllocateFromLookasideListEx 會在驅動程式將 NULLAllocate 和 Free 指標傳遞至 ExInitializeLookasideListEx 時,自動呼叫 ExAllocatePoolWithTag 和 ExFreePool。
任何驅動程式提供的 Allocate 例程都不得為分頁集區中的專案配置記憶體,以保留在非分頁的 lookaside 清單中,反之亦然。 它也必須配置固定大小的條目,因為任何後續的驅動程式呼叫 ExAllocateFromLookasideListEx 都會傳回目前保留在 lookaside 清單中的第一個條目,除非清單是空的。 也就是說,呼叫 ExAllocateFromLookasideListEx 只會在指定的 lookaside 列表是空的時,才會呼叫驅動程式提供的 Allocate 例程。 因此,每次呼叫 ExAllocateFromLookasideListEx 時,傳回的項目只有在 lookaside 清單中的所有項目都是固定大小時,才會符合驅動程式所需的大小。 驅動程式提供的 Allocate 例程不應該變更驅動程式原本傳遞至 ExInitializeLookasideListEx 的 Tag 值,因為集區標籤值中的變更會使偵錯和追蹤驅動程式的記憶體使用量變得更困難。
呼叫 ExFreeToLookasideListEx 將之前配置的專案儲存在 lookaside 清單中,除非清單已經 滿(即,清單包含系統決定的最大項目數)。 為了獲得更好的效能,驅動程式應該盡可能快速地呼叫 ExFreeToLookasideListEx,以對應每次呼叫 ExAllocateFromLookasideListEx。 當一個驅動程式快速地將條目釋放回其外觀清單時,該驅動程式下一次調用 ExAllocateFromLookasideListEx 的時候,比較不容易因為動態分配新條目的記憶體而遭遇效能懲罰。
類似的指導方針適用於使用 PAGED_LOOKASIDE_LIST 或 NPAGED_LOOKASIDE_LIST 結構的旁視列表。