mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 01:35:43 +00:00
- 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:
parent
8f5fca485e
commit
36e302cc70
1 changed files with 128 additions and 111 deletions
|
@ -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,29 +210,8 @@ 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,
|
||||||
Mdl,
|
Mdl,
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -225,30 +256,10 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
|
DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_offset.QuadPart = offset * PAGE_SIZE;
|
|
||||||
RetrievalPointers = PagingFileList[i]->RetrievalPointers;
|
|
||||||
|
|
||||||
for (j = 0; j < RetrievalPointers->NumberOfPairs; j++)
|
file_offset.QuadPart = offset * PAGE_SIZE;
|
||||||
{
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
||||||
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,33 +802,57 @@ 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)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(FileObject);
|
while (RetDescList)
|
||||||
NtClose(FileHandle);
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
CurrentRetDescList = RetDescList;
|
||||||
|
RetDescList = RetDescList->Next;
|
||||||
|
ExFreePool(CurrentRetDescList);
|
||||||
|
}
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
PagingFile->FileObject = FileObject;
|
PagingFile->FileObject = FileObject;
|
||||||
|
@ -858,42 +869,48 @@ 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);
|
||||||
NtClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
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 ||
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue