kernel/eka/memmodel/epoc/flexible/mmu/mmanager.cpp
branchRCL_3
changeset 41 0ffb4e86fcc9
parent 28 5b5d147c7838
equal deleted inserted replaced
39:2bb754abd467 41:0ffb4e86fcc9
   129 
   129 
   130 
   130 
   131 TInt DMemoryManager::MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
   131 TInt DMemoryManager::MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
   132 								TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest)
   132 								TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest)
   133 	{
   133 	{
       
   134 	MmuLock::Unlock();
   134 	return KErrNotSupported;
   135 	return KErrNotSupported;
   135 	}
   136 	}
   136 
   137 
   137 
   138 
   138 TInt DMemoryManager::MoveAndAllocPage(DMemoryObject*, SPageInfo*, TZonePageType)
   139 TInt DMemoryManager::MoveAndAllocPage(DMemoryObject*, SPageInfo*, TZonePageType)
   747 
   748 
   748 TInt DMovableMemoryManager::MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
   749 TInt DMovableMemoryManager::MovePage(	DMemoryObject* aMemory, SPageInfo* aOldPageInfo, 
   749 										TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest)
   750 										TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest)
   750 	{
   751 	{
   751 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
   752 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
   752 
   753 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   753 	// Allocate the new page to move to, ensuring that we use the page type of the
   754 	TInt r = KErrInUse;
   754 	// manager assigned to this page.
       
   755 	TPhysAddr newPage;
       
   756 	Mmu& m = TheMmu;
       
   757 	TInt r = m.AllocRam(&newPage, 1, aMemory->RamAllocFlags(), aMemory->iManager->PageType(), 
       
   758 						aBlockZoneId, aBlockRest);
       
   759 	if (r != KErrNone)
       
   760 		{// Failed to allocate a new page to move the page to so can't continue.
       
   761 		return r;
       
   762 		}
       
   763 	
       
   764 	r = KErrInUse;
       
   765 	MmuLock::Lock();
       
   766 
   755 
   767 	TUint index = aOldPageInfo->Index();
   756 	TUint index = aOldPageInfo->Index();
   768 	TRACE(	("DMovableMemoryManager::MovePage(0x%08x,0x%08x,?,0x%08x,%d) index=0x%x",
   757 	TRACE(	("DMovableMemoryManager::MovePage(0x%08x,0x%08x,?,0x%08x,%d) index=0x%x",
   769 			aMemory,aOldPageInfo,aBlockZoneId,aBlockRest,index));
   758 			aMemory,aOldPageInfo,aBlockZoneId,aBlockRest,index));
   770 	__NK_ASSERT_DEBUG(aMemory==aOldPageInfo->Owner());
   759 	__NK_ASSERT_DEBUG(aMemory==aOldPageInfo->Owner());
   773 	RPageArray::TIter pageIter;
   762 	RPageArray::TIter pageIter;
   774 	TPhysAddr* const movingPageArrayPtr = aMemory->iPages.MovePageStart(index, pageIter);
   763 	TPhysAddr* const movingPageArrayPtr = aMemory->iPages.MovePageStart(index, pageIter);
   775 	if (!movingPageArrayPtr)
   764 	if (!movingPageArrayPtr)
   776 		{// Can't move the page another operation is being performed on it.
   765 		{// Can't move the page another operation is being performed on it.
   777 		MmuLock::Unlock();
   766 		MmuLock::Unlock();
   778 		TheMmu.FreeRam(&newPage, 1, aMemory->iManager->PageType());
       
   779 		return r;
   767 		return r;
   780 		}
   768 		}
   781 	__NK_ASSERT_DEBUG(RPageArray::IsPresent(*movingPageArrayPtr));
   769 	__NK_ASSERT_DEBUG(RPageArray::IsPresent(*movingPageArrayPtr));
   782 	TPhysAddr oldPageEntry = *movingPageArrayPtr;
   770 	TPhysAddr oldPageEntry = *movingPageArrayPtr;
   783 	TPhysAddr oldPage = oldPageEntry & ~KPageMask;
   771 	TPhysAddr oldPage = oldPageEntry & ~KPageMask;
   786 		{// The address of page array entry and the page info should match except
   774 		{// The address of page array entry and the page info should match except
   787 		// when the page is being shadowed.
   775 		// when the page is being shadowed.
   788 		__NK_ASSERT_DEBUG(SPageInfo::FromPhysAddr(oldPage)->Type() == SPageInfo::EShadow);
   776 		__NK_ASSERT_DEBUG(SPageInfo::FromPhysAddr(oldPage)->Type() == SPageInfo::EShadow);
   789 		}
   777 		}
   790 #endif
   778 #endif
       
   779 	// Set the modifier so we can detect if the page state is updated.
       
   780 	aOldPageInfo->SetModifier(&pageIter);
       
   781 
       
   782 	MmuLock::Unlock();
       
   783 
       
   784 	// Allocate the new page to move to, ensuring that we use the page type of the
       
   785 	// manager assigned to this page.
       
   786 	TPhysAddr newPage;
       
   787 	Mmu& m = TheMmu;
       
   788 	TInt allocRet = m.AllocRam(&newPage, 1, aMemory->RamAllocFlags(), aMemory->iManager->PageType(), 
       
   789 						aBlockZoneId, aBlockRest);
       
   790 	if (allocRet != KErrNone)
       
   791 		{
       
   792 		MmuLock::Lock();
       
   793 		aMemory->iPages.MovePageEnd(*movingPageArrayPtr, index);
       
   794 		MmuLock::Unlock();
       
   795 		return allocRet;
       
   796 		}
       
   797 
   791 	__NK_ASSERT_DEBUG((newPage & KPageMask) == 0);
   798 	__NK_ASSERT_DEBUG((newPage & KPageMask) == 0);
   792 	__NK_ASSERT_DEBUG(newPage != oldPage);
   799 	__NK_ASSERT_DEBUG(newPage != oldPage);
   793 
   800 
   794 	// Set the modifier so we can detect if the page state is updated.
   801 	MmuLock::Lock();
   795 	aOldPageInfo->SetModifier(&pageIter);
   802 	if (aOldPageInfo->CheckModified(&pageIter) ||
   796 
   803 		oldPageEntry != *movingPageArrayPtr)
   797 	// Restrict the page ready for moving.
   804 		{// The page was modified or freed.
       
   805 		aMemory->iPages.MovePageEnd(*movingPageArrayPtr, index);
       
   806 		MmuLock::Unlock();
       
   807 		m.FreeRam(&newPage, 1, aMemory->iManager->PageType());
       
   808 		return r;
       
   809 		}
       
   810 	MmuLock::Unlock();
       
   811 
       
   812 	// This page's contents may be changed so restrict the page to no access 
       
   813 	// so we can detect any access to it while we are moving it.
   798 	// Read only memory objects don't need to be restricted but we still need
   814 	// Read only memory objects don't need to be restricted but we still need
   799 	// to discover any physically pinned mappings.
   815 	// to discover any physically pinned mappings.
   800 	TBool pageRestrictedNA = !aMemory->IsReadOnly();
   816 	TBool pageRestrictedNA = !aMemory->IsReadOnly();
   801 	TRestrictPagesType restrictType = 	pageRestrictedNA ? 
   817 	TRestrictPagesType restrictType = 	pageRestrictedNA ? 
   802 										ERestrictPagesNoAccessForMoving :
   818 										ERestrictPagesNoAccessForMoving :
   803 										ERestrictPagesForMovingFlag;
   819 										ERestrictPagesForMovingFlag;
   804 
   820 
   805 	// This page's contents may be changed so restrict the page to no access 
       
   806 	// so we can detect any access to it while we are moving it.
       
   807 	MmuLock::Unlock();
       
   808 	// This will clear the memory objects mapping added flag so we can detect any new mappings.
   821 	// This will clear the memory objects mapping added flag so we can detect any new mappings.
   809 	aMemory->RestrictPages(pageIter, restrictType);
   822 	aMemory->RestrictPages(pageIter, restrictType);
   810 
   823 
   811 	const TUint KOldMappingSlot = 0;
   824 	const TUint KOldMappingSlot = 0;
   812 	const TUint KNewMappingSlot = 1;
   825 	const TUint KNewMappingSlot = 1;
   889 #else
   902 #else
   890 		}
   903 		}
   891 #endif
   904 #endif
   892 	// indicate we've stopped moving memory now...
   905 	// indicate we've stopped moving memory now...
   893 	MmuLock::Lock();
   906 	MmuLock::Lock();
   894 	RPageArray::MovePageEnd(*movingPageArrayPtr);
   907 	aMemory->iPages.MovePageEnd(*movingPageArrayPtr, index);
   895 	MmuLock::Unlock();
   908 	MmuLock::Unlock();
   896 
   909 
   897 	return r;
   910 	return r;
   898 	}
   911 	}
   899 
   912