Author: ros-arm-bringup
Date: Sat Jun 27 06:56:58 2009
New Revision: 41626
URL:
http://svn.reactos.org/svn/reactos?rev=41626&view=rev
Log:
- Implement MiReleaseSystemPtes which is the function to deallocate System PTE
allocations.
- We do some minor optimizations to combine chunks if possible after a free, similar to
MD Block algorithms in freeldr.c.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/syspte.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/syspte.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/syspte.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/syspte.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/syspte.c [iso-8859-1] Sat Jun 27 06:56:58 2009
@@ -160,6 +160,170 @@
VOID
NTAPI
+MiReleaseSystemPtes(IN PMMPTE StartingPte,
+ IN ULONG NumberOfPtes,
+ IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
+{
+ ULONG_PTR ClusterSize, CurrentSize;
+ PMMPTE CurrentPte, NextPte, PointerPte;
+
+ //
+ // Check to make sure the PTE address is within bounds.
+ //
+ ASSERT(NumberOfPtes != 0);
+ ASSERT(StartingPte >= MmSystemPtesStart[SystemPtePoolType]);
+ ASSERT(StartingPte <= MmSystemPtesEnd[SystemPtePoolType]);
+
+ //
+ // Zero PTEs.
+ //
+ RtlZeroMemory(StartingPte, NumberOfPtes * sizeof (MMPTE));
+
+ //
+ // Increase availability
+ //
+ MmTotalFreeSystemPtes[SystemPtePoolType] += NumberOfPtes;
+
+ //
+ // Get the free cluster and start going through them
+ //
+ CurrentSize = (ULONG_PTR)(StartingPte - MmSystemPteBase);
+ CurrentPte = &MmFirstFreeSystemPte[SystemPtePoolType];
+ while (TRUE)
+ {
+ //
+ // Get the first real cluster of PTEs and check if it's ours
+ //
+ PointerPte = MmSystemPteBase + CurrentPte->u.List.NextEntry;
+ if (CurrentSize < CurrentPte->u.List.NextEntry)
+ {
+ //
+ // Sanity check
+ //
+ ASSERT(((StartingPte + NumberOfPtes) <= PointerPte) ||
+ (CurrentPte->u.List.NextEntry == -1));
+
+ //
+ // Get the next cluster in case it's the one
+ //
+ NextPte = CurrentPte + 1;
+
+ //
+ // Check if this was actually a single-PTE entry
+ //
+ if (CurrentPte->u.List.OneEntry)
+ {
+ //
+ // We only have one page
+ //
+ ClusterSize = 1;
+ }
+ else
+ {
+ //
+ // The next cluster will have the page count
+ //
+ ClusterSize = (ULONG_PTR)NextPte->u.List.NextEntry;
+ }
+
+ //
+ // So check if this cluster actually describes the entire mapping
+ //
+ if ((CurrentPte + ClusterSize) == StartingPte)
+ {
+ //
+ // It does -- collapse the free PTEs into the next cluster
+ //
+ NumberOfPtes += ClusterSize;
+ NextPte->u.List.NextEntry = NumberOfPtes;
+ CurrentPte->u.List.OneEntry = 0;
+
+ //
+ // Make another pass
+ //
+ StartingPte = CurrentPte;
+ }
+ else
+ {
+ //
+ // There's still PTEs left -- make us into a cluster
+ //
+ StartingPte->u.List.NextEntry = CurrentPte->u.List.NextEntry;
+ CurrentPte->u.List.NextEntry = CurrentSize;
+
+ //
+ // Is there just one page left?
+ //
+ if (NumberOfPtes == 1)
+ {
+ //
+ // Then this actually becomes a single PTE entry
+ //
+ StartingPte->u.List.OneEntry = 1;
+ }
+ else
+ {
+ //
+ // Otherwise, create a new cluster for the remaining pages
+ //
+ StartingPte->u.List.OneEntry = 0;
+ NextPte = StartingPte + 1;
+ NextPte->u.List.NextEntry = NumberOfPtes;
+ }
+ }
+
+ //
+ // Now check if we've arrived at yet another cluster
+ //
+ if ((StartingPte + NumberOfPtes) == PointerPte)
+ {
+ //
+ // We'll collapse the next cluster into us
+ //
+ StartingPte->u.List.NextEntry = PointerPte->u.List.NextEntry;
+ StartingPte->u.List.OneEntry = 0;
+ NextPte = StartingPte + 1;
+
+ //
+ // Check if the cluster only had one page
+ //
+ if (PointerPte->u.List.OneEntry)
+ {
+ //
+ // So will we...
+ //
+ ClusterSize = 1;
+ }
+ else
+ {
+ //
+ // Otherwise, grab the page count from the next-next cluster
+ //
+ PointerPte++;
+ ClusterSize = (ULONG_PTR)PointerPte->u.List.NextEntry;
+ }
+
+ //
+ // And create the final combined cluster
+ //
+ NextPte->u.List.NextEntry = NumberOfPtes + ClusterSize;
+ }
+
+ //
+ // We released the PTEs into their cluster (and optimized the list)
+ //
+ break;
+ }
+
+ //
+ // Try the next cluster of PTEs...
+ //
+ CurrentPte = PointerPte;
+ }
+}
+
+VOID
+NTAPI
MiInitializeSystemPtes(IN PMMPTE StartingPte,
IN ULONG NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE PoolType)