mirror of
https://github.com/reactos/reactos.git
synced 2025-01-13 01:22:03 +00:00
- Implement the rest of the nonpaged pool allocator, now with support for allocating pages in the nonpaged pool expansion area.
- This uses System PTEs, so if you're still not sick of the same old mantra -- optimizations to the former will help the latter. - Additionally, we should eventually implement a single-page SLIST for nonpaged pool pages, which will greately improve allocate/free of 1 page. - As a reminder, this code isn't being used yet. svn path=/trunk/; revision=41933
This commit is contained in:
parent
d9b66b43bd
commit
1279c44e6c
1 changed files with 72 additions and 6 deletions
|
@ -130,11 +130,12 @@ NTAPI
|
|||
MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
||||
IN SIZE_T SizeInBytes)
|
||||
{
|
||||
PFN_NUMBER SizeInPages;
|
||||
PFN_NUMBER SizeInPages, PageFrameNumber;
|
||||
ULONG i;
|
||||
KIRQL OldIrql;
|
||||
PLIST_ENTRY NextEntry, NextHead, LastHead;
|
||||
PMMPTE PointerPte;
|
||||
PMMPTE PointerPte, StartPte;
|
||||
MMPTE TempPte;
|
||||
PMMPFN Pfn1;
|
||||
PVOID BaseVa;
|
||||
PMMFREE_POOL_ENTRY FreeEntry;
|
||||
|
@ -258,13 +259,78 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
|||
// If we got here, we're out of space.
|
||||
// Start by releasing the lock
|
||||
//
|
||||
KeReleaseQueuedSpinLock (LockQueueMmNonPagedPoolLock, OldIrql);
|
||||
KeReleaseQueuedSpinLock(LockQueueMmNonPagedPoolLock, OldIrql);
|
||||
|
||||
//
|
||||
// Allocate some system PTEs
|
||||
//
|
||||
StartPte = MiReserveSystemPtes(SizeInPages, NonPagedPoolExpansion);
|
||||
PointerPte = StartPte;
|
||||
if (StartPte == NULL)
|
||||
{
|
||||
//
|
||||
// Ran out of memory
|
||||
//
|
||||
DPRINT1("Out of NP Expansion Pool\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// We should now go into expansion nonpaged pool
|
||||
// Acquire the pool lock now
|
||||
//
|
||||
DPRINT1("Out of NP Pool\n");
|
||||
return NULL;
|
||||
OldIrql = KeAcquireQueuedSpinLock(LockQueueMmNonPagedPoolLock);
|
||||
|
||||
//
|
||||
// Lock the PFN database too
|
||||
//
|
||||
//KeAcquireQueuedSpinLockAtDpcLevel(LockQueuePfnLock);
|
||||
|
||||
//
|
||||
// Loop the pages
|
||||
//
|
||||
TempPte = HyperTemplatePte;
|
||||
do
|
||||
{
|
||||
//
|
||||
// Allocate a page
|
||||
//
|
||||
PageFrameNumber = MmAllocPage(MC_NPPOOL, 0);
|
||||
|
||||
//
|
||||
// Get the PFN entry for it
|
||||
//
|
||||
Pfn1 = MiGetPfnEntry(PageFrameNumber);
|
||||
|
||||
//
|
||||
// Write the PTE for it
|
||||
//
|
||||
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
|
||||
ASSERT(PointerPte->u.Hard.Valid == 0);
|
||||
ASSERT(TempPte.u.Hard.Valid == 1);
|
||||
*PointerPte++ = TempPte;
|
||||
} while (--SizeInPages > 0);
|
||||
|
||||
//
|
||||
// This is the last page
|
||||
//
|
||||
Pfn1->u3.e1.EndOfAllocation = 1;
|
||||
|
||||
//
|
||||
// Get the first page and mark it as such
|
||||
//
|
||||
Pfn1 = MiGetPfnEntry(StartPte->u.Hard.PageFrameNumber);
|
||||
Pfn1->u3.e1.StartOfAllocation = 1;
|
||||
|
||||
//
|
||||
// Release the PFN and nonpaged pool lock
|
||||
//
|
||||
//KeReleaseQueuedSpinLockFromDpcLevel(LockQueuePfnLock);
|
||||
KeReleaseQueuedSpinLock(LockQueueMmNonPagedPoolLock, OldIrql);
|
||||
|
||||
//
|
||||
// Return the address
|
||||
//
|
||||
return MiPteToAddress(StartPte);
|
||||
}
|
||||
|
||||
ULONG
|
||||
|
|
Loading…
Reference in a new issue