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

새 lookaside-list 항목을 할당하는 호출자 제공 LookasideListAllocateEx 루틴에 대한 포인터입니다. Lookaside 목록이 비어 있는 경우 ExAllocateFromLookasideListEx 루틴은 이 LookasideListAllocateEx 루틴을 호출합니다(항목이 없음). 이 매개 변수는 선택 사항이며 사용자 지정 할당 루틴이 필요하지 않은 경우 NULL 로 지정할 수 있습니다. 이 매개 변수가 NULL인 경우 ExAllocateFromPagedLookasideList 를 호출하면 새 항목에 대해 Paged 또는 nonpaged 스토리지( PoolType 매개 변수에 의해 결정됨)가 자동으로 할당됩니다.

[in, optional] Free

이전에 할당된 lookaside-list 항목을 해제하는 호출자 제공 LookasideListFreeEx 루틴에 대한 포인터입니다. ExFreeToPagedLookasideList 루틴은 lookaside 목록이 가득 차면 이 LookasideListFreeEx 루틴을 호출합니다(즉, 목록에 운영 체제에 의해 결정된 최대 항목 수가 이미 포함됨). 이 매개 변수는 선택 사항이며 사용자 지정 할당 취소 루틴이 필요하지 않은 경우 NULL 로 지정할 수 있습니다. 이 매개 변수가 NULL인 경우 ExFreeToPagedLookasideList 를 호출하면 지정된 항목에 대한 스토리지가 자동으로 해제됩니다.

[in] PoolType

lookaside 목록에 있는 항목의 풀 유형을 지정합니다. 이 매개 변수를 유효한 POOL_TYPE 열거형 값으로 설정합니다.

[in] Flags

LookasideListAllocateEx 루틴의 기본 동작을 수정하는 선택적 플래그 값을 지정합니다. 이 매개 변수를 0으로 설정하거나 다음 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와 같은 할당 루틴과 함께 사용하기 위한 것입니다.

이 두 플래그 비트는 상호 배타적입니다.

할당NULL인 경우 플래그를 0 또는 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 플래그 비트와 함께 비트 ORed가 되어 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 플래그 비트와 함께 비트 ORed가 되어 LookasideListAllocateEx 루틴에 전달되는 PoolType 매개 변수 값을 형성합니다. LookasideListAllocateEx 루틴은 수정 없이 이 PoolType 값을 ExAllocatePoolWithQuotaTag 루틴에 전달할 수 있습니다. POOL_QUOTA_FAIL_INSTEAD_OF_RAISE 플래그에 대한 자세한 내용은 ExAllocatePoolWithQuotaTag를 참조하세요.

[in] Size

lookaside 목록에 있는 각 항목의 크기(바이트)를 지정합니다.

[in] Tag

lookaside-list 항목에 할당된 스토리지를 표시하는 데 사용할 4바이트 풀 태그를 지정합니다. 풀 태그에 대한 자세한 내용은 ExAllocatePoolWithTagTag 매개 변수에 대한 설명을 참조하세요.

[in] Depth

예약되어 있습니다. 항상 이 매개 변수를 0으로 설정합니다.

반환 값

ExInitializeLookasideListEx 는 호출이 성공하면 STATUS_SUCCESS 반환합니다. 가능한 반환 값에는 다음 오류 코드가 포함됩니다.

반환 코드 설명
STATUS_INVALID_PARAMETER_4 PoolType 매개 변수 값이 잘못되었습니다.
STATUS_INVALID_PARAMETER_5 Flags 매개 변수 값이 잘못되었습니다.

설명

드라이버가 목록을 사용하기 시작하려면 먼저 드라이버가 이 루틴을 호출하여 lookaside 목록을 초기화해야 합니다. lookaside 목록은 드라이버가 로컬로 관리하여 시스템 할당 루틴에 대한 호출 수를 줄이고 성능을 향상시키기 위해 관리할 수 있는 고정 크기 버퍼 풀입니다. 버퍼는 lookaside 목록에 항목으로 저장됩니다. 목록의 모든 항목은 크기 매개 변수로 지정된 동일한 균일한 크기입니다.

ExInitializeLookasideListEx가 반환되면 lookaside 목록이 초기화되지만 항목은 포함되지 않습니다. 클라이언트가 ExAllocateFromLookasideListEx 루틴을 호출하여 항목을 요청하는 경우 이 루틴은 lookaside 목록이 비어 있음을 확인하고 드라이버 제공 LookasideListAllocateEx 루틴을 호출하여 새 항목에 대한 스토리지를 동적으로 할당합니다. 클라이언트의 유사한 요청에 대한 응답으로 추가 항목이 할당될 수 있습니다. 나중에 클라이언트가 ExFreeToLookasideListEx 를 호출하여 이러한 항목을 해제하면 이 루틴은 항목을 lookaside 목록에 삽입합니다. 목록의 항목 수가 운영 체제에 의해 결정되는 제한에 도달하면 ExFreeToLookasideListEx 는 목록에 항목을 더 추가하지 않고 대신 드라이버 제공 LookasideListFreeEx 루틴에 전달하여 해제합니다.

드라이버가 LookasideListAllocateExLookasideListFreeEx 루틴을 제공하지 않는 경우 ExAllocateFromLookasideListExExFreeToLookasideListEx 루틴은 기본 할당 및 할당 취소 루틴을 대신 사용합니다.

ExAllocatePoolWithTagExFreePool을 호출하는 것 외에는 아무 작업도 수행하지 않는 LookasideListAllocateExLookasideListFreeEx 루틴을 제공하는 이점은 없습니다. 할당무료 매개 변수를 NULL로 설정하면 성능이 향상되어 동일한 효과를 달성할 수 있습니다.

드라이버가 언로드되기 전에 만든 lookaside 목록을 명시적으로 해제해야 합니다. 이렇게 하지 않으면 심각한 프로그래밍 오류가 발생합니다. ExDeleteLookasideListEx 루틴을 호출하여 lookaside 목록을 해제합니다. 이 루틴은 지정된 lookaside 목록의 나머지 항목에 대한 스토리지를 해제한 다음 시스템 전체의 활성 lookaside 목록 집합에서 목록을 제거합니다.

운영 체제는 현재 사용 중인 모든 lookaside 목록을 추적합니다. 사용 가능한 비페이징 메모리 양과 lookaside 목록 항목에 대한 수요는 시간이 지남에 따라 달라지므로 운영 체제는 각 비페이지형 lookaside 목록의 최대 항목 수에 대한 제한을 동적으로 조정합니다.

Windows 2000 이상 버전의 Windows에서는 페이지가 지정되거나 페이지가 지정되지 않은 항목이 포함된 lookaside 목록을 각각 PAGED_LOOKASIDE_LIST 또는 NPAGED_LOOKASIDE_LIST 구조로 설명할 수 있습니다.

lookaside 목록에 대한 자세한 내용은 Lookaside Lists 사용을 참조하세요.

ExInitializeLookasideListEx의 호출자는 IRQL <= DISPATCH_LEVEL 실행할 수 있지만 일반적으로 IRQL = PASSIVE_LEVEL 실행됩니다.

예제

드라이버에서 제공하는 LookasideListAllocateExLookasideListFreeEx 루틴은 모두 lookaside 목록을 설명하는 LOOKASIDE_LIST_EX 구조를 가리키는 Lookaside 매개 변수를 받습니다. 루틴은 이 매개 변수를 사용하여 드라이버가 lookaside 목록과 연결한 개인 데이터에 액세스할 수 있습니다. 예를 들어 드라이버는 다음 구조의 instance 할당하여 만든 각 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 루틴이 반환되면 ExAllocateFromLookasideListExNewEntry 변수가 가리키는 버퍼를 lookaside 목록에 삽입합니다. 이 삽입 작업을 스레드로부터 안전하게 만들기 위해 ExAllocateFromLookasideListEx 는 lookaside 목록의 액세스를 다른 스레드에서 수행할 수 있는 다른 목록 삽입 및 제거 작업과 동기화합니다. 마찬가지로 ExFreeFromLookasideListEx 가 lookaside 목록에서 버퍼를 제거하면 목록에 대한 액세스를 동기화합니다.

ExAllocateFromLookasideListExExFreeFromLookasideListEx 는 드라이버 제공 LookasideListAllocateExLookasideListFreeEx 루틴에 대한 호출을 동기화하지 않습니다. 따라서 이전 코드 예제의 MyLookasideListAllocateExMyLookasideListFreeEx 루틴이 스레드로부터 안전해야 하는 경우 드라이버는 필요한 동기화를 제공해야 합니다.

예제 루틴인 MyLookasideListAllocateExMyContext-NumberOfAllocations> 변수의 액세스를 이 변수를 증가시키고 감소시킬 수 있는 다른 스레드와 동기화합니다. 이 동기화를 제공하기 위해 MyLookasideListAllocateExInterlockedIncrement 루틴을 호출하여 이 변수를 원자성으로 증가합니다. 마찬가지로 MyLookasideListFreeEx 루틴(표시되지 않음)은 InterlockedDecrement 루틴을 호출하여 이 변수를 원자적으로 감소할 수 있습니다.

그러나 앞의 코드 예제에서 MyContext-NumberOfAllocations> 변수의 유일한 목적이 단순히 lookaside 목록 할당에 대한 통계를 수집하는 것일 경우 원자성 증가 및 감소는 거의 필요하지 않습니다. 이 경우 누락된 증가 또는 감소의 원격 가능성은 문제가 되지 않습니다.

lookaside 목록의 스레드 보안에 대한 자세한 내용은 Lookaside Lists 사용을 참조하세요.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows Vista부터 사용할 수 있습니다.
대상 플랫폼 유니버설
헤더 wdm.h(Wdm.h, Ntddk.h, Ntifs.h 포함)
라이브러리 NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL(주의 섹션 참조)

추가 정보

ExAllocateFromLookasideListEx

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTag

ExDeleteLookasideListEx

ExFreePool

ExFreeToLookasideListEx

InterlockedDecrement

InterlockedIncrement

LOOKASIDE_LIST_EX

LookasideListAllocateEx

LookasideListFreeEx

NPAGED_LOOKASIDE_LIST

PAGED_LOOKASIDE_LIST

POOL_TYPE