Author: ros-arm-bringup
Date: Sun Jul 12 17:02:05 2009
New Revision: 41933
URL:
http://svn.reactos.org/svn/reactos?rev=41933&view=rev
Log:
- 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.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Sun Jul 12 17:02:05 2009
@@ -130,11 +130,12 @@
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 @@
// If we got here, we're out of space.
// Start by releasing the lock
//
- KeReleaseQueuedSpinLock (LockQueueMmNonPagedPoolLock, OldIrql);
-
- //
- // We should now go into expansion nonpaged pool
- //
- DPRINT1("Out of NP Pool\n");
- return NULL;
+ 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;
+ }
+
+ //
+ // Acquire the pool lock now
+ //
+ 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