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 루틴은 lookaside 목록이 비어 있는 경우 이 LookasideListAllocateEx 루틴을 호출합니다(항목 없음). 이 매개 변수는 선택 사항이며 사용자 지정 할당 루틴이 필요하지 않은 경우 NULL 지정할 수 있습니다. 이 매개 변수가 NULL 경우 ExAllocateFromPagedLookasideList에 대한 호출은 새 항목에 대해 페이징되거나 페이지가 지정되지 않은 스토리지(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 플래그 비트 중 하나로 설정합니다.
플래그 비트 | 묘사 |
---|---|
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 매개 변수 값은 LookasideListAllocateEx 루틴에 전달되는 PoolType 매개 변수 값을 형성하기 위해 POOL_RAISE_IF_ALLOCATION_FAILURE 플래그 비트와 함께 비트 ORed됩니다. LookasideListAllocateEx 루틴은 수정 없이 이 PoolType 값을 ExAllocatePoolWithTag 루틴에 전달할 수 있습니다. POOL_RAISE_IF_ALLOCATION_FAILURE 플래그에 대한 자세한 내용은 ExAllocatePoolWithTag참조하세요.
Flags = EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE 경우 PoolType 매개 변수 값은 LookasideListAllocateEx 루틴에 전달되는 PoolType 매개 변수 값을 형성하기 위해 POOL_QUOTA_FAIL_INSTEAD_OF_RAISE 플래그 비트와 함께 비트 ORed됩니다. 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 목록에 항목으로 저장됩니다. 목록의 모든 항목은 동일한 균일한 크기이며 Size 매개 변수로 지정됩니다.
exInitializeLookasideListEx 반환되면 lookaside 목록이 초기화되지만 항목은 포함되지 않습니다. 클라이언트가 ExAllocateFromLookasideListEx 루틴을 호출하여 항목을 요청하는 경우 이 루틴은 lookaside 목록이 비어 있음을 확인하고 드라이버 제공 LookasideListAllocateEx 루틴을 호출하여 새 항목에 대한 스토리지를 동적으로 할당합니다. 클라이언트의 유사한 요청에 대한 응답으로 추가 항목이 할당될 수 있습니다. 나중에 클라이언트가 ExFreeToLookasideListEx 호출하여 이러한 항목을 해제하면 이 루틴은 항목을 lookaside 목록에 삽입합니다. 목록의 항목 수가 운영 체제에 의해 결정되는 제한에 도달하면 ExFreeToLookasideListEx 목록에 항목을 더 이상 추가하지 않고 대신 드라이버에서 제공하는 LookasideListFreeEx 루틴에 전달합니다.
드라이버가 lookasideListAllocateEx 및 lookasideListFreeEx 루틴을 제공하지 않으면 ExAllocateFromLookasideListEx 및 ExFreeToLookasideListEx 루틴은 기본 할당 및 할당 취소 루틴을 대신 사용합니다.
LookasideListAllocateEx 및 LookasideListFreeExExAllocatePoolWithTag 호출하고 ExFreePool 루틴을 제공하는 이점은 없습니다. 할당 설정하고 무료 매개 변수를 NULL 더 나은 성능으로 동일한 효과를 달성할 수 있습니다.
드라이버가 언로드되기 전에 만든 lookaside 목록을 명시적으로 해제해야 합니다. 이렇게 하지 않으면 심각한 프로그래밍 오류가 발생합니다. ExDeleteLookasideListEx 루틴을 호출하여 lookaside 목록을 해제합니다. 이 루틴은 지정된 lookaside 목록의 나머지 항목에 대한 스토리지를 해제한 다음 시스템 전체의 활성 lookaside 목록 집합에서 목록을 제거합니다.
운영 체제는 현재 사용 중인 모든 lookaside 목록을 추적합니다. 사용 가능한 비페이징된 메모리 양과 lookaside 목록 항목에 대한 수요는 시간이 지남에 따라 달라지므로 운영 체제는 페이지가 없는 각 lookaside 목록의 최대 항목 수에 대한 제한을 동적으로 조정합니다.
Windows 2000 이상 버전의 Windows에서는 페이징된 항목이나 페이지가 지정되지 않은 항목이 포함된 lookaside 목록을 각각 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 루틴이 반환되면 ExAllocateFromLookasideListExNewEntry 변수가 가리키는 버퍼를 lookaside 목록에 삽입합니다. 이 삽입 작업을 스레드로부터 안전하게 만들려면 ExAllocateFromLookasideListEx lookaside 목록의 액세스를 다른 스레드에서 수행할 수 있는 다른 목록 삽입 및 제거 작업과 동기화합니다. 마찬가지로, ExFreeFromLookasideListEx lookaside 목록에서 버퍼를 제거하면 목록에 대한 액세스가 동기화됩니다.
ExAllocateFromLookasideListEx 및 ExFreeFromLookasideListEx 드라이버 제공 LookasideListAllocateEx 및 LookasideListFreeEx 루틴에 대한 호출을 동기화하지 않습니다. 따라서 앞의 코드 예제에서 MyLookasideListAllocateEx 및 MyLookasideListFreeEx 루틴이 스레드로부터 안전해야 하는 경우 드라이버는 필요한 동기화를 제공해야 합니다.
MyLookasideListAllocateEx 예제 루틴은 MyContext->NumberOfAllocations 변수에 대한 액세스를 이 변수를 증가시키고 감소시킬 수 있는 다른 스레드와 동기화합니다. 이 동기화를 제공하려면 myLookasideListAllocateEx InterlockedIncrement 루틴을 호출하여 이 변수를 원자성으로 증가합니다. 마찬가지로, MyLookasideListFreeEx 루틴(표시되지 않음)은 InterlockedDecrement 루틴을 호출하여 이 변수를 원자성으로 감소할 수 있습니다.
그러나 앞의 코드 예제에서 MyContext->NumberOfAllocations 변수의 유일한 목적은 단순히 lookaside 목록 할당에 대한 통계를 수집하는 것일 경우 원자성 증가 및 감소는 거의 필요하지 않습니다. 이 경우 누락된 증가 또는 감소의 원격 가능성은 문제가 되지 않습니다.
lookaside 목록의 스레드 보안에 대한 자세한 내용은 lookaside 목록 사용하는참조하세요.
요구 사항
요구 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows Vista부터 사용할 수 있습니다. |
대상 플랫폼 | 보편적 |
헤더 | wdm.h(Wdm.h, Ntddk.h, Ntifs.h 포함) |
라이브러리 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL(주의 섹션 참조) |