Author: sir_richard Date: Wed May 12 22:57:21 2010 New Revision: 47184
URL: http://svn.reactos.org/svn/reactos?rev=47184&view=rev Log: [NTOS]: Move MiFindContiguousPages to ARM3/contmem.c since I don't know what it was doing in freelist.c. No code change.
Modified: trunk/reactos/ntoskrnl/mm/ARM3/contmem.c trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/freelist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/contmem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/contmem.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/contmem.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/contmem.c [iso-8859-1] Wed May 12 22:57:21 2010 @@ -17,6 +17,194 @@ #include "../ARM3/miarm.h"
/* PRIVATE FUNCTIONS **********************************************************/ + +PFN_NUMBER +NTAPI +MiFindContiguousPages(IN PFN_NUMBER LowestPfn, + IN PFN_NUMBER HighestPfn, + IN PFN_NUMBER BoundaryPfn, + IN PFN_NUMBER SizeInPages, + IN MEMORY_CACHING_TYPE CacheType) +{ + PFN_NUMBER Page, PageCount, LastPage, Length, BoundaryMask; + ULONG i = 0; + PMMPFN Pfn1, EndPfn; + KIRQL OldIrql; + PAGED_CODE (); + ASSERT(SizeInPages != 0); + + // + // Convert the boundary PFN into an alignment mask + // + BoundaryMask = ~(BoundaryPfn - 1); + + // + // Loop all the physical memory blocks + // + do + { + // + // Capture the base page and length of this memory block + // + Page = MmPhysicalMemoryBlock->Run[i].BasePage; + PageCount = MmPhysicalMemoryBlock->Run[i].PageCount; + + // + // Check how far this memory block will go + // + LastPage = Page + PageCount; + + // + // Trim it down to only the PFNs we're actually interested in + // + if ((LastPage - 1) > HighestPfn) LastPage = HighestPfn + 1; + if (Page < LowestPfn) Page = LowestPfn; + + // + // Skip this run if it's empty or fails to contain all the pages we need + // + if (!(PageCount) || ((Page + SizeInPages) > LastPage)) continue; + + // + // Now scan all the relevant PFNs in this run + // + Length = 0; + for (Pfn1 = MiGetPfnEntry(Page); Page < LastPage; Page++, Pfn1++) + { + // + // If this PFN is in use, ignore it + // + if (MiIsPfnInUse(Pfn1)) continue; + + // + // If we haven't chosen a start PFN yet and the caller specified an + // alignment, make sure the page matches the alignment restriction + // + if ((!(Length) && (BoundaryPfn)) && + (((Page ^ (Page + SizeInPages - 1)) & BoundaryMask))) + { + // + // It does not, so bail out + // + continue; + } + + // + // Increase the number of valid pages, and check if we have enough + // + if (++Length == SizeInPages) + { + // + // It appears we've amassed enough legitimate pages, rollback + // + Pfn1 -= (Length - 1); + Page -= (Length - 1); + + // + // Acquire the PFN lock + // + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + do + { + // + // Things might've changed for us. Is the page still free? + // + if (MiIsPfnInUse(Pfn1)) break; + + // + // So far so good. Is this the last confirmed valid page? + // + if (!--Length) + { + // + // Sanity check that we didn't go out of bounds + // + ASSERT(i != MmPhysicalMemoryBlock->NumberOfRuns); + + // + // Loop until all PFN entries have been processed + // + EndPfn = Pfn1 - SizeInPages + 1; + do + { + // + // This PFN is now a used page, set it up + // + MiUnlinkFreeOrZeroedPage(Pfn1); + Pfn1->u3.e2.ReferenceCount = 1; + + // + // Check if it was already zeroed + // + if (Pfn1->u3.e1.PageLocation != ZeroedPageList) + { + // + // It wasn't, so zero it + // + MiZeroPage(MiGetPfnEntryIndex(Pfn1)); + } + + // + // Mark it in use + // + Pfn1->u3.e1.PageLocation = ActiveAndValid; + + // + // Check if this is the last PFN, otherwise go on + // + if (Pfn1 == EndPfn) break; + Pfn1--; + } while (TRUE); + + // + // Mark the first and last PFN so we can find them later + // + Pfn1->u3.e1.StartOfAllocation = 1; + (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1; + + // + // Now it's safe to let go of the PFN lock + // + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + // + // Quick sanity check that the last PFN is consistent + // + EndPfn = Pfn1 + SizeInPages; + ASSERT(EndPfn == MiGetPfnEntry(Page + 1)); + + // + // Compute the first page, and make sure it's consistent + // + Page -= SizeInPages - 1; + ASSERT(Pfn1 == MiGetPfnEntry(Page)); + ASSERT(Page != 0); + return Page; + } + + // + // Keep going. The purpose of this loop is to reconfirm that + // after acquiring the PFN lock these pages are still usable + // + Pfn1++; + Page++; + } while (TRUE); + + // + // If we got here, something changed while we hadn't acquired + // the PFN lock yet, so we'll have to restart + // + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + Length = 0; + } + } + } while (++i != MmPhysicalMemoryBlock->NumberOfRuns); + + // + // And if we get here, it means no suitable physical memory runs were found + // + return 0; +}
PVOID NTAPI
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed May 12 22:57:21 2010 @@ -621,4 +621,10 @@ VOID );
+BOOLEAN +NTAPI +MiIsPfnInUse( + IN PMMPFN Pfn1 +); + /* EOF */
Modified: trunk/reactos/ntoskrnl/mm/freelist.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Wed May 12 22:57:21 2010 @@ -145,194 +145,6 @@ { /* Standby list or higher, unlinked, and with references */ return !MiIsPfnFree(Pfn1); -} - -PFN_NUMBER -NTAPI -MiFindContiguousPages(IN PFN_NUMBER LowestPfn, - IN PFN_NUMBER HighestPfn, - IN PFN_NUMBER BoundaryPfn, - IN PFN_NUMBER SizeInPages, - IN MEMORY_CACHING_TYPE CacheType) -{ - PFN_NUMBER Page, PageCount, LastPage, Length, BoundaryMask; - ULONG i = 0; - PMMPFN Pfn1, EndPfn; - KIRQL OldIrql; - PAGED_CODE (); - ASSERT(SizeInPages != 0); - - // - // Convert the boundary PFN into an alignment mask - // - BoundaryMask = ~(BoundaryPfn - 1); - - // - // Loop all the physical memory blocks - // - do - { - // - // Capture the base page and length of this memory block - // - Page = MmPhysicalMemoryBlock->Run[i].BasePage; - PageCount = MmPhysicalMemoryBlock->Run[i].PageCount; - - // - // Check how far this memory block will go - // - LastPage = Page + PageCount; - - // - // Trim it down to only the PFNs we're actually interested in - // - if ((LastPage - 1) > HighestPfn) LastPage = HighestPfn + 1; - if (Page < LowestPfn) Page = LowestPfn; - - // - // Skip this run if it's empty or fails to contain all the pages we need - // - if (!(PageCount) || ((Page + SizeInPages) > LastPage)) continue; - - // - // Now scan all the relevant PFNs in this run - // - Length = 0; - for (Pfn1 = MiGetPfnEntry(Page); Page < LastPage; Page++, Pfn1++) - { - // - // If this PFN is in use, ignore it - // - if (MiIsPfnInUse(Pfn1)) continue; - - // - // If we haven't chosen a start PFN yet and the caller specified an - // alignment, make sure the page matches the alignment restriction - // - if ((!(Length) && (BoundaryPfn)) && - (((Page ^ (Page + SizeInPages - 1)) & BoundaryMask))) - { - // - // It does not, so bail out - // - continue; - } - - // - // Increase the number of valid pages, and check if we have enough - // - if (++Length == SizeInPages) - { - // - // It appears we've amassed enough legitimate pages, rollback - // - Pfn1 -= (Length - 1); - Page -= (Length - 1); - - // - // Acquire the PFN lock - // - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - do - { - // - // Things might've changed for us. Is the page still free? - // - if (MiIsPfnInUse(Pfn1)) break; - - // - // So far so good. Is this the last confirmed valid page? - // - if (!--Length) - { - // - // Sanity check that we didn't go out of bounds - // - ASSERT(i != MmPhysicalMemoryBlock->NumberOfRuns); - - // - // Loop until all PFN entries have been processed - // - EndPfn = Pfn1 - SizeInPages + 1; - do - { - // - // This PFN is now a used page, set it up - // - MiUnlinkFreeOrZeroedPage(Pfn1); - Pfn1->u3.e2.ReferenceCount = 1; - - // - // Check if it was already zeroed - // - if (Pfn1->u3.e1.PageLocation != ZeroedPageList) - { - // - // It wasn't, so zero it - // - MiZeroPage(MiGetPfnEntryIndex(Pfn1)); - } - - // - // Mark it in use - // - Pfn1->u3.e1.PageLocation = ActiveAndValid; - - // - // Check if this is the last PFN, otherwise go on - // - if (Pfn1 == EndPfn) break; - Pfn1--; - } while (TRUE); - - // - // Mark the first and last PFN so we can find them later - // - Pfn1->u3.e1.StartOfAllocation = 1; - (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1; - - // - // Now it's safe to let go of the PFN lock - // - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - - // - // Quick sanity check that the last PFN is consistent - // - EndPfn = Pfn1 + SizeInPages; - ASSERT(EndPfn == MiGetPfnEntry(Page + 1)); - - // - // Compute the first page, and make sure it's consistent - // - Page -= SizeInPages - 1; - ASSERT(Pfn1 == MiGetPfnEntry(Page)); - ASSERT(Page != 0); - return Page; - } - - // - // Keep going. The purpose of this loop is to reconfirm that - // after acquiring the PFN lock these pages are still usable - // - Pfn1++; - Page++; - } while (TRUE); - - // - // If we got here, something changed while we hadn't acquired - // the PFN lock yet, so we'll have to restart - // - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - Length = 0; - } - } - } while (++i != MmPhysicalMemoryBlock->NumberOfRuns); - - // - // And if we get here, it means no suitable physical memory runs were found - // - return 0; }
PMDL