mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 07:05:12 +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
|
@ -130,11 +130,12 @@ NTAPI
|
||||||
MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
||||||
IN SIZE_T SizeInBytes)
|
IN SIZE_T SizeInBytes)
|
||||||
{
|
{
|
||||||
PFN_NUMBER SizeInPages;
|
PFN_NUMBER SizeInPages, PageFrameNumber;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PLIST_ENTRY NextEntry, NextHead, LastHead;
|
PLIST_ENTRY NextEntry, NextHead, LastHead;
|
||||||
PMMPTE PointerPte;
|
PMMPTE PointerPte, StartPte;
|
||||||
|
MMPTE TempPte;
|
||||||
PMMPFN Pfn1;
|
PMMPFN Pfn1;
|
||||||
PVOID BaseVa;
|
PVOID BaseVa;
|
||||||
PMMFREE_POOL_ENTRY FreeEntry;
|
PMMFREE_POOL_ENTRY FreeEntry;
|
||||||
|
@ -258,13 +259,78 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
|
||||||
// If we got here, we're out of space.
|
// If we got here, we're out of space.
|
||||||
// Start by releasing the lock
|
// 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");
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueMmNonPagedPoolLock);
|
||||||
return NULL;
|
|
||||||
|
//
|
||||||
|
// 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
|
ULONG
|
||||||
|
|
Loading…
Reference in a new issue