kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
changeset 132 e4a7b1cbe40c
parent 121 661475905584
child 176 af6ec97d9189
equal deleted inserted replaced
131:e880629062dd 132:e4a7b1cbe40c
   305 	}
   305 	}
   306 
   306 
   307 
   307 
   308 TInt DPager::PageFreed(SPageInfo* aPageInfo)
   308 TInt DPager::PageFreed(SPageInfo* aPageInfo)
   309 	{
   309 	{
       
   310 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
   310 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   311 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   311 	__NK_ASSERT_DEBUG(CheckLists());
   312 	__NK_ASSERT_DEBUG(CheckLists());
   312 
   313 
   313 	switch(aPageInfo->PagedState())
   314 	switch(aPageInfo->PagedState())
   314 		{
   315 		{
   349 
   350 
   350 	case SPageInfo::EPagedPinnedMoved:
   351 	case SPageInfo::EPagedPinnedMoved:
   351 		// This page was pinned when it was moved but it has not been returned 
   352 		// This page was pinned when it was moved but it has not been returned 
   352 		// to the free pool yet so make sure it is...
   353 		// to the free pool yet so make sure it is...
   353 		aPageInfo->SetPagedState(SPageInfo::EUnpaged);	// Must be unpaged before returned to free pool.
   354 		aPageInfo->SetPagedState(SPageInfo::EUnpaged);	// Must be unpaged before returned to free pool.
   354 		return KErrNotFound;
   355 		return KErrCompletion;
   355 
   356 
   356 	default:
   357 	default:
   357 		__NK_ASSERT_DEBUG(0);
   358 		__NK_ASSERT_DEBUG(0);
   358 		return KErrNotFound;
   359 		return KErrNotFound;
   359 		}
   360 		}
   363 		{
   364 		{
   364 		aPageInfo->SetReadOnly();
   365 		aPageInfo->SetReadOnly();
   365 		SetClean(*aPageInfo);
   366 		SetClean(*aPageInfo);
   366 		}
   367 		}
   367 
   368 
       
   369 	if (iNumberOfFreePages > 0)
       
   370 		{// The paging cache is not at the minimum size so safe to let the 
       
   371 		// ram allocator free this page.
       
   372 		iNumberOfFreePages--;
       
   373 		aPageInfo->SetPagedState(SPageInfo::EUnpaged);
       
   374 		return KErrCompletion;
       
   375 		}
       
   376 	// Need to hold onto this page as have reached the page cache limit.
   368 	// add as oldest page...
   377 	// add as oldest page...
   369 	aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
   378 	aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
   370 	iOldestCleanList.Add(&aPageInfo->iLink);
   379 	iOldestCleanList.Add(&aPageInfo->iLink);
   371 	++iOldestCleanCount;
   380 	++iOldestCleanCount;
   372 
   381 
   411 		__NK_ASSERT_DEBUG(0);
   420 		__NK_ASSERT_DEBUG(0);
   412 	case SPageInfo::EUnpaged:
   421 	case SPageInfo::EUnpaged:
   413 #ifdef _DEBUG
   422 #ifdef _DEBUG
   414 		if (!IsPageTableUnpagedRemoveAllowed(aPageInfo))
   423 		if (!IsPageTableUnpagedRemoveAllowed(aPageInfo))
   415 			__NK_ASSERT_DEBUG(0);
   424 			__NK_ASSERT_DEBUG(0);
       
   425 #endif
   416 		break;
   426 		break;
   417 #endif
       
   418 	default:
   427 	default:
   419 		__NK_ASSERT_DEBUG(0);
   428 		__NK_ASSERT_DEBUG(0);
   420 		return;
   429 		return;
   421 		}
   430 		}
   422 
   431 
   801 	TRACE(("DPager::StealPage returns %d",r));
   810 	TRACE(("DPager::StealPage returns %d",r));
   802 	return r;
   811 	return r;
   803 	}
   812 	}
   804 
   813 
   805 
   814 
       
   815 TInt DPager::DiscardAndAllocPage(SPageInfo* aPageInfo, TZonePageType aPageType)
       
   816 	{
       
   817 	TInt r = DiscardPage(aPageInfo, KRamZoneInvalidId, EFalse);
       
   818 	if (r == KErrNone)
       
   819 		{
       
   820 		TheMmu.MarkPageAllocated(aPageInfo->PhysAddr(), aPageType);
       
   821 		}
       
   822 	// Flash the ram alloc lock as we may have had to write a page out to swap.
       
   823 	RamAllocLock::Unlock();
       
   824 	RamAllocLock::Lock();
       
   825 	return r;
       
   826 	}
       
   827 
       
   828 
   806 static TBool DiscardCanStealPage(SPageInfo* aOldPageInfo, TBool aBlockRest)
   829 static TBool DiscardCanStealPage(SPageInfo* aOldPageInfo, TBool aBlockRest)
   807 	{
   830 	{
   808  	// If the page is pinned or if the page is dirty and a general defrag is being performed then
   831  	// If the page is pinned or if the page is dirty and a general defrag is being performed then
   809 	// don't attempt to steal it
   832 	// don't attempt to steal it
   810 	return aOldPageInfo->Type() == SPageInfo::EUnused ||
   833 	return aOldPageInfo->Type() == SPageInfo::EUnused ||
  1000 	__NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
  1023 	__NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
  1001 
  1024 
  1002 	__NK_ASSERT_DEBUG(iNumberOfFreePages>0);
  1025 	__NK_ASSERT_DEBUG(iNumberOfFreePages>0);
  1003 	--iNumberOfFreePages;
  1026 	--iNumberOfFreePages;
  1004 
  1027 
       
  1028 	// The page must be unpaged, otherwise it wasn't successfully removed 
       
  1029 	// from the live list.
       
  1030 	__NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
  1005 	MmuLock::Unlock();
  1031 	MmuLock::Unlock();
  1006 
  1032 
  1007 	TPhysAddr pagePhys = aPageInfo.PhysAddr();
  1033 	TPhysAddr pagePhys = aPageInfo.PhysAddr();
  1008 	TheMmu.FreeRam(&pagePhys, 1, EPageDiscard);
  1034 	TheMmu.FreeRam(&pagePhys, 1, EPageDiscard);
  1009 
  1035 
  2066 
  2092 
  2067 	return r;
  2093 	return r;
  2068 	}
  2094 	}
  2069 
  2095 
  2070 
  2096 
       
  2097 // WARNING THIS METHOD MAY HOLD THE RAM ALLOC LOCK FOR EXCESSIVE PERIODS.  DON'T USE THIS IN ANY PRODUCTION CODE.
  2071 void DPager::FlushAll()
  2098 void DPager::FlushAll()
  2072 	{
  2099 	{
  2073 	NKern::ThreadEnterCS();
  2100 	NKern::ThreadEnterCS();
  2074 	RamAllocLock::Lock();
  2101 	RamAllocLock::Lock();
  2075 	PageCleaningLock::Lock();
  2102 	PageCleaningLock::Lock();
  2106 						MmuLock::Flash();
  2133 						MmuLock::Flash();
  2107 						}
  2134 						}
  2108 					}
  2135 					}
  2109 				++pi;
  2136 				++pi;
  2110 				if(((TUint)pi&(0xf<<KPageInfoShift))==0)
  2137 				if(((TUint)pi&(0xf<<KPageInfoShift))==0)
       
  2138 					{
  2111 					MmuLock::Flash(); // every 16 page infos
  2139 					MmuLock::Flash(); // every 16 page infos
       
  2140 					}
  2112 				}
  2141 				}
  2113 			while(pi<piEnd);
  2142 			while(pi<piEnd);
  2114 			}
  2143 			}
  2115 		pi = piNext;
  2144 		pi = piNext;
  2116 		}
  2145 		}