- Use binary search for the offset within the pagefile.

- Reduce the overhead for retrieving the sector offsets for page files while initialisation.

svn path=/trunk/; revision=6823
This commit is contained in:
Hartmut Birr 2003-11-30 17:19:28 +00:00
parent 8f5fca485e
commit 36e302cc70

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: pagefile.c,v 1.38 2003/11/17 02:12:51 hyperion Exp $ /* $Id: pagefile.c,v 1.39 2003/11/30 17:19:28 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pagefile.c * FILE: ntoskrnl/mm/pagefile.c
@ -55,8 +55,17 @@ typedef struct _PAGINGFILE
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers; PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
} PAGINGFILE, *PPAGINGFILE; } PAGINGFILE, *PPAGINGFILE;
typedef struct _RETRIEVEL_DESCRIPTOR_LIST
{
struct _RETRIEVEL_DESCRIPTOR_LIST* Next;
GET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
}
RETRIEVEL_DESCRIPTOR_LIST, *PRETRIEVEL_DESCRIPTOR_LIST;
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
#define PAIRS_PER_RUN (1024)
#define MAX_PAGING_FILES (32) #define MAX_PAGING_FILES (32)
/* List of paging files, both used and free */ /* List of paging files, both used and free */
@ -124,14 +133,58 @@ MmShowOutOfSpaceMessagePagingFile(VOID)
} }
} }
LARGE_INTEGER STATIC
MmGetOffsetPageFile(PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers, LARGE_INTEGER Offset)
{
/* Simple binary search */
ULONG first, last, mid;
first = 0;
last = RetrievalPointers->NumberOfPairs - 1;
while (first <= last)
{
mid = (last - first) / 2 + first;
if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid].Vcn)
{
if (mid == 0)
{
Offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn;
return Offset;
}
else
{
if ((ULONGLONG) Offset.QuadPart >= RetrievalPointers->Pair[mid-1].Vcn)
{
Offset.QuadPart += RetrievalPointers->Pair[mid].Lcn - RetrievalPointers->Pair[mid-1].Vcn;
return Offset;
}
last = mid - 1;
}
}
else
{
if (mid == RetrievalPointers->NumberOfPairs - 1)
{
break;
}
if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid+1].Vcn)
{
Offset.QuadPart += RetrievalPointers->Pair[mid+1].Lcn - RetrievalPointers->Pair[mid].Vcn;
return Offset;
}
first = mid + 1;
}
}
KEBUGCHECK(0);
return (LARGE_INTEGER)0LL;
}
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
{ {
ULONG i, offset, j; ULONG i, offset;
LARGE_INTEGER file_offset; LARGE_INTEGER file_offset;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
KEVENT Event; KEVENT Event;
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
DPRINT("MmWriteToSwapPage\n"); DPRINT("MmWriteToSwapPage\n");
@ -157,28 +210,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
} }
file_offset.QuadPart = offset * PAGE_SIZE; file_offset.QuadPart = offset * PAGE_SIZE;
RetrievalPointers = PagingFileList[i]->RetrievalPointers; file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
for (j = 0; j < RetrievalPointers->NumberOfPairs; j++)
{
if ((ULONGLONG) file_offset.QuadPart < RetrievalPointers->Pair[j].Vcn)
{
if (j == 0)
{
file_offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn;
}
else
{
file_offset.QuadPart += RetrievalPointers->Pair[j].Lcn - RetrievalPointers->Pair[j-1].Vcn;
}
break;
}
}
if (j >= RetrievalPointers->NumberOfPairs)
{
CHECKPOINT1;
KEBUGCHECK(0);
}
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageWrite(PagingFileList[i]->FileObject, Status = IoPageWrite(PagingFileList[i]->FileObject,
@ -196,12 +228,11 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
{ {
ULONG i, offset, j; ULONG i, offset;
LARGE_INTEGER file_offset; LARGE_INTEGER file_offset;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
KEVENT Event; KEVENT Event;
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
DPRINT("MmReadFromSwapPage\n"); DPRINT("MmReadFromSwapPage\n");
@ -227,28 +258,8 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
} }
file_offset.QuadPart = offset * PAGE_SIZE; file_offset.QuadPart = offset * PAGE_SIZE;
RetrievalPointers = PagingFileList[i]->RetrievalPointers; file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
for (j = 0; j < RetrievalPointers->NumberOfPairs; j++)
{
if ((ULONGLONG) file_offset.QuadPart < RetrievalPointers->Pair[j].Vcn)
{
if (j == 0)
{
file_offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn;
}
else
{
file_offset.QuadPart += RetrievalPointers->Pair[j].Lcn - RetrievalPointers->Pair[j-1].Vcn;
}
break;
}
}
if (j >= RetrievalPointers->NumberOfPairs)
{
CHECKPOINT1;
KEBUGCHECK(0);
}
KeInitializeEvent(&Event, NotificationEvent, FALSE); KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageRead(PagingFileList[i]->FileObject, Status = IoPageRead(PagingFileList[i]->FileObject,
Mdl, Mdl,
@ -435,33 +446,6 @@ MmAllocSwapPage(VOID)
return(0); return(0);
} }
LARGE_INTEGER STATIC
MmGetOffsetPageFile(PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers, LARGE_INTEGER Offset)
{
ULONG j;
for (j = 0; j < RetrievalPointers->NumberOfPairs; j++)
{
if (Offset.QuadPart < RetrievalPointers->Pair[j].Vcn)
{
if (j == 0)
{
Offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn;
}
else
{
Offset.QuadPart += RetrievalPointers->Pair[j].Lcn - RetrievalPointers->Pair[j-1].Vcn;
}
break;
}
}
if (j >= RetrievalPointers->NumberOfPairs)
{
CHECKPOINT1;
KEBUGCHECK(0);
}
return(Offset);
}
NTSTATUS STDCALL NTSTATUS STDCALL
MmDumpToPagingFile(ULONG BugCode, MmDumpToPagingFile(ULONG BugCode,
ULONG BugCodeParameter1, ULONG BugCodeParameter1,
@ -712,12 +696,14 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
ULONG AllocMapSize; ULONG AllocMapSize;
ULONG Size; ULONG Size;
FILE_FS_SIZE_INFORMATION FsSizeInformation; FILE_FS_SIZE_INFORMATION FsSizeInformation;
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers; PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
PRETRIEVEL_DESCRIPTOR_LIST CurrentRetDescList;
ULONG i; ULONG i;
ULONG BytesPerAllocationUnit; ULONG BytesPerAllocationUnit;
LARGE_INTEGER Vcn; LARGE_INTEGER Vcn;
ULONG ExtentCount; ULONG ExtentCount;
ULONG MaxVcn; ULONG MaxVcn;
ULONG Count;
DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
FileName, InitialSize->QuadPart); FileName, InitialSize->QuadPart);
@ -793,9 +779,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
return(Status); return(Status);
} }
RetrievalPointers = ExAllocatePool(NonPagedPool, sizeof(GET_RETRIEVAL_DESCRIPTOR) + sizeof(MAPPING_PAIR)); Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + PAIRS_PER_RUN * sizeof(MAPPING_PAIR);
CurrentRetDescList = RetDescList = ExAllocatePool(NonPagedPool, Size);
if (RetrievalPointers == NULL) if (CurrentRetDescList == NULL)
{ {
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
NtClose(FileHandle); NtClose(FileHandle);
@ -815,30 +802,54 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
FSCTL_GET_RETRIEVAL_POINTERS, FSCTL_GET_RETRIEVAL_POINTERS,
&Vcn, &Vcn,
sizeof(LARGE_INTEGER), sizeof(LARGE_INTEGER),
RetrievalPointers, &CurrentRetDescList->RetrievalPointers,
sizeof(GET_RETRIEVAL_DESCRIPTOR) + sizeof(MAPPING_PAIR)); sizeof(GET_RETRIEVAL_DESCRIPTOR) + PAIRS_PER_RUN * sizeof(MAPPING_PAIR));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExFreePool(RetrievalPointers); while (RetDescList)
{
CurrentRetDescList = RetDescList;
RetDescList = RetDescList->Next;
ExFreePool(CurrentRetDescList);
}
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
NtClose(FileHandle); NtClose(FileHandle);
return(Status); return(Status);
} }
ExtentCount += RetrievalPointers->NumberOfPairs; ExtentCount += CurrentRetDescList->RetrievalPointers.NumberOfPairs;
if ((ULONG)RetrievalPointers->Pair[0].Vcn < MaxVcn) if ((ULONG)CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn < MaxVcn)
{ {
Vcn.QuadPart = RetrievalPointers->Pair[0].Vcn; CurrentRetDescList->Next = ExAllocatePool(NonPagedPool, Size);
if (CurrentRetDescList->Next == NULL)
{
while (RetDescList)
{
CurrentRetDescList = RetDescList;
RetDescList = RetDescList->Next;
ExFreePool(CurrentRetDescList);
}
ObDereferenceObject(FileObject);
NtClose(FileHandle);
return(STATUS_NO_MEMORY);
}
Vcn.QuadPart = CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn;
CurrentRetDescList = CurrentRetDescList->Next;
} }
else else
{ {
break; break;
} }
} }
ExFreePool(RetrievalPointers);
PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile)); PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile));
if (PagingFile == NULL) if (PagingFile == NULL)
{ {
while (RetDescList)
{
CurrentRetDescList = RetDescList;
RetDescList = RetDescList->Next;
ExFreePool(CurrentRetDescList);
}
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
NtClose(FileHandle); NtClose(FileHandle);
return(STATUS_NO_MEMORY); return(STATUS_NO_MEMORY);
@ -858,16 +869,28 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
if (PagingFile->AllocMap == NULL) if (PagingFile->AllocMap == NULL)
{ {
while (RetDescList)
{
CurrentRetDescList = RetDescList;
RetDescList = RetDescList->Next;
ExFreePool(CurrentRetDescList);
}
ExFreePool(PagingFile); ExFreePool(PagingFile);
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
ZwClose(FileHandle); ZwClose(FileHandle);
return(STATUS_NO_MEMORY); return(STATUS_NO_MEMORY);
} }
DPRINT("ExtentCount: %d\n", ExtentCount);
Size = sizeof(GET_RETRIEVAL_DESCRIPTOR) + ExtentCount * sizeof(MAPPING_PAIR); Size = sizeof(GET_RETRIEVAL_DESCRIPTOR) + ExtentCount * sizeof(MAPPING_PAIR);
PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size); PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size);
if (PagingFile->RetrievalPointers == NULL) if (PagingFile->RetrievalPointers == NULL)
{ {
while (RetDescList)
{
CurrentRetDescList = RetDescList;
RetDescList = RetDescList->Next;
ExFreePool(CurrentRetDescList);
}
ExFreePool(PagingFile->AllocMap); ExFreePool(PagingFile->AllocMap);
ExFreePool(PagingFile); ExFreePool(PagingFile);
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
@ -875,25 +898,19 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
return(STATUS_NO_MEMORY); return(STATUS_NO_MEMORY);
} }
Vcn.QuadPart = 0LL; Count = 0;
Status = NtFsControlFile(FileHandle, PagingFile->RetrievalPointers->NumberOfPairs = ExtentCount;
0, PagingFile->RetrievalPointers->StartVcn = RetDescList->RetrievalPointers.StartVcn;
NULL, CurrentRetDescList = RetDescList;
NULL, while (CurrentRetDescList)
&IoStatus,
FSCTL_GET_RETRIEVAL_POINTERS,
&Vcn,
sizeof(LARGE_INTEGER),
PagingFile->RetrievalPointers,
Size);
if (!NT_SUCCESS(Status))
{ {
ExFreePool(PagingFile->RetrievalPointers); memcpy(&PagingFile->RetrievalPointers->Pair[Count],
ExFreePool(PagingFile->AllocMap); CurrentRetDescList->RetrievalPointers.Pair,
ExFreePool(PagingFile); CurrentRetDescList->RetrievalPointers.NumberOfPairs * sizeof(MAPPING_PAIR));
ObDereferenceObject(FileObject); Count += CurrentRetDescList->RetrievalPointers.NumberOfPairs;
NtClose(FileHandle); RetDescList = CurrentRetDescList;
return(STATUS_NO_MEMORY); CurrentRetDescList = CurrentRetDescList->Next;
ExFreePool(RetDescList);
} }
if (PagingFile->RetrievalPointers->NumberOfPairs != ExtentCount || if (PagingFile->RetrievalPointers->NumberOfPairs != ExtentCount ||