kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp
branchGCC_SURGE
changeset 221 39b39e1a406e
parent 201 43365a9b78a3
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp	Wed Jul 21 14:46:58 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp	Thu Jul 22 16:46:39 2010 +0100
@@ -115,51 +115,89 @@
 	RamAllocLock::Lock();
 
 	// Move the page to any RAM zone.
-	r = M::MovePage(aOld, aNew, KRamZoneInvalidId, EFalse);
+	r = M::MovePage(aOld, aNew, KRamZoneInvalidId, 0);
 
 	RamAllocLock::Unlock();
 	return r;
 	}
 
 
-TInt M::MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)
+TInt M::MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TUint aMoveDisFlags)
 	{
-	TInt r;
+	// Returns this when page is not paged or managed or free but is a real RAM page.
+	TInt r = KErrNotSupported;
 
 	// get memory object corresponding to the page...
 	DMemoryObject* memory = 0;
 	MmuLock::Lock();
-	SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aOld&~KPageMask);
+	SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aOld & ~KPageMask);
+	if (pi)
+		{
+		if (pi->PagedState() != SPageInfo::EUnpaged)
+			{// The page is paged so let the pager handle it.
+			return ThePager.DiscardPage(pi, aBlockZoneId, aMoveDisFlags);
+			}
+		switch (pi->Type())
+			{
+			case SPageInfo::EManaged:
+				memory = pi->Owner();
+				memory->Open();
+				// move page, this will release the mmu lock.
+				r = memory->iManager->MovePage(	memory, pi, aNew, aBlockZoneId, 
+												(aMoveDisFlags & M::EMoveDisBlockRest)!=0);
+				memory->AsyncClose();
+				break;
+			case SPageInfo::EUnused:
+				r = KErrNotFound;	// This page is free so nothing to do.
+				// Fall through..
+			default:
+				MmuLock::Unlock();
+			}
+		}
+	else
+		{// page info for aOld not found so aOld is not a RAM page...
+		MmuLock::Unlock();
+		r = KErrArgument;
+		}
+	return r;
+	}
+
+
+TInt M::MoveAndAllocPage(TPhysAddr aAddr, TZonePageType aPageType)
+	{
+	// Returns this when page is not paged or managed or free but is a real RAM page.
+	TInt r = KErrNotSupported;
+
+	// get memory object corresponding to the page...
+	DMemoryObject* memory = 0;
+	MmuLock::Lock();
+	SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aAddr & ~KPageMask);
 	if(pi)
 		{
 		if (pi->PagedState() != SPageInfo::EUnpaged)
 			{// The page is paged so let the pager handle it.
-			return ThePager.DiscardPage(pi, aBlockZoneId, aBlockRest);
+			return ThePager.DiscardAndAllocPage(pi, aPageType);
 			}
-		if (pi->Type()==SPageInfo::EManaged)
-			memory = pi->Owner();
-		}
-	MmuLock::Unlock();
-
-	// Note, whilst we hold the RamAllocLock the page can't change it's use
-	// and we can safely assume that it still belongs to the memory object
-	// at a fixed page index.
-	// Also, as memory objects can't be destroyed whilst they still own pages
-	// we can safely access this object without taking an explicit referernce,
-	// i.e. we don't need to Open() the memory object.
-	if (!pi)
-		{// page info for aOld not found so aOld is not a RAM page...
-		r = KErrArgument;
-		}
-	else if(!memory)
-		{
-		// page does not have a memory manager, so we can't move it...
-		r = KErrNotSupported;
+		switch (pi->Type())
+			{
+			case SPageInfo::EManaged:
+				memory = pi->Owner();
+				memory->Open();
+				// move page, this will release the mmu lock.
+				r = memory->iManager->MoveAndAllocPage(memory, pi, aPageType);
+				memory->AsyncClose();
+				break;
+			case SPageInfo::EUnused:
+				r = KErrNone;	// This page is free so nothing to do.
+				// Fall through..
+			default:
+				MmuLock::Unlock();
+			}
 		}
 	else
-		{
-		// move page...
-		r = memory->iManager->MovePage(memory, pi, aNew, aBlockZoneId, aBlockRest);
+		{// page info for aAddr not found so aAddr is not a RAM page...
+		MmuLock::Unlock();
+		r = KErrArgument;
 		}
 	return r;
 	}