Heap 관리자는 메모리 블럭의 크기가 무작위로 결정되기 때문에 인접한 free 블럭을 합치기 위해 많은 CPU 시간을 요구하게 됩니다.


항상 고정된 크기의 메모리 블럭만을 사용한다면 heap을 관리하는데 있어 훨씬 효율적인 방식으로 사용이 가능한데 예를 들면

큰 메모리 블럭을 미리 할당하여, 이를 주어진 크기로 조각냅니다. 블럭이 heap에 리턴되면 실제로 해제하는 것이 아니라 사용이

끝남으로 표시하면서 사용하게 되는데, 이에 대한 몇가지 문제점이 있습니다.


너무 많은 메모리를 할당할 경우는 메모리 낭비를 가져올 수 있고, 너무 적게 할당할 경우는 알고리즘이 동작하지 않거나 더 많은 블럭을 얻으려고 heap 관리자를 너무 자주 사용하게 되는 것입니다.


Microsoft에서는 이러한 단점을 극복하기 위해 lookaside list 객체를 제공합니다.


lookaside list

  1. lookaside list 객체 초기화시 시스템에게 작업할 단위 메모리 블럭의 크기를 알립니다. ( 용량은 운영체제가 탄력적으로 감지합니다. )
  2. 메모리 블럭을 할당하기 위해서 시스템은 일단 하나의 블럭의 제거를 시도합니다.
    1. 더 이상 남은 블럭이 없다면 메모리 pool에서 빼옵니다.
  3. 메모리 블럭을 반환하려면, 시스템은 리스트에 되돌리기를 시도하게 되며, 리스트가 꽉 차면 일반 heap 관리 루틴을 사용해서 pool에 블럭을 되돌립니다.

시스템은 실제 사용에 따라 모든 lookaside list의 depth를 정기적으로 조작합니다.

  • 시스템에 최근 접근하지 않았거나, 총 시간에서 5% 이상 액세스 하지 않은 lookaside list에 대해 depth를 감소 시킵니다.
  • 처음의 새 리스트 값인 4 이하로는 줄어들지 않습니다.
  • driver verifier 실행시는 모든 lookaside list의 depth는 모두 0으로 바뀝니다. ( 메모리 오류와 관련된 드라이버 문제를 발견하기 쉽게 하기 위해서 입니다. )

Lookaside list 지원 함수

Lookaside list를 지원하는 함수는 paged / non-paged 두 분류로 나뉘게 됩니다.

  • ExInitializeNPagedLookasideList  / ExInitializePagedLookasideList : Lookaside list를 초기화 한다.
  • ExAllocateFromNPagedLookasideList / ExAllocateFromPagedLookasideList : 고정된 크기의 블럭을 할당한다.  
  • ExFreeToNPagedLookasideList / ExFreeToPagedLookasideList : 해제해서 lookaside list로 다시 돌려준다.
  • ExDeleteNPagedLookasideList / ExDeletePagedLookasideList : Lookaside list를 삭제한다.


lookaside list 객체를 위해 메모리를 확보하고 나서 적절한 초기화 루틴을 호출합니다.


각 함수에서 첫 번째 인수는 이미 공간을 확보해둔 (N)PAGED_LOOKASIDE_LIST 객체에 대한 포인터입니다. Allocate와 Free는 heap에서 메모리를 할당하거나 해제할 수 있는 루틴들에 대한 포인터 입니다. ExAllocatePoolWithTag와 ExFreePool을 쓸 시에는 이 인수들을 NULL로 하면 됩니다. blocksize 인수는 리스트에서 할당하는 메모리 블럭의 크기를 나타냅니다. tag는 이러한 각 블럭의 앞에 붙은 32비트 태그 값입니다.


리스트에서 메모리 블럭을 할당하려면 적절한 AllocateFrom 함수를 호출한다.

PVOID p = ExAllocateFromPagedLookasideList(pagelist);

PVOID p = ExAllocateFromNPagedLookasideList(nonpagedlist);

블럭을 리스트로 다시 돌리려면 적절한 FreeTo 함수를 호출하면 됩니다.

ExFreeToPagedLookasideList(pagedlist, p);

ExFreeToNPagedLookasideList(nonpagedlist, p);

마지막으로 리스트를 제거하려면 적절한 Delete 함수를 호출하면 됩니다.

ExDeletePagedLookasideList(pagedlist);

ExDeleteNPagedLookasideList(nonpagedlist);

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Fast I/O  (0) 2010.03.18

+ Recent posts