--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Thu May 27 14:17:14 2010 +0300
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Fri Jun 11 15:02:23 2010 +0300
@@ -307,6 +307,7 @@
TInt DPager::PageFreed(SPageInfo* aPageInfo)
{
+ __NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
__NK_ASSERT_DEBUG(MmuLock::IsHeld());
__NK_ASSERT_DEBUG(CheckLists());
@@ -351,7 +352,7 @@
// This page was pinned when it was moved but it has not been returned
// to the free pool yet so make sure it is...
aPageInfo->SetPagedState(SPageInfo::EUnpaged); // Must be unpaged before returned to free pool.
- return KErrNotFound;
+ return KErrCompletion;
default:
__NK_ASSERT_DEBUG(0);
@@ -365,6 +366,14 @@
SetClean(*aPageInfo);
}
+ if (iNumberOfFreePages > 0)
+ {// The paging cache is not at the minimum size so safe to let the
+ // ram allocator free this page.
+ iNumberOfFreePages--;
+ aPageInfo->SetPagedState(SPageInfo::EUnpaged);
+ return KErrCompletion;
+ }
+ // Need to hold onto this page as have reached the page cache limit.
// add as oldest page...
aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
iOldestCleanList.Add(&aPageInfo->iLink);
@@ -413,8 +422,8 @@
#ifdef _DEBUG
if (!IsPageTableUnpagedRemoveAllowed(aPageInfo))
__NK_ASSERT_DEBUG(0);
+#endif
break;
-#endif
default:
__NK_ASSERT_DEBUG(0);
return;
@@ -803,6 +812,20 @@
}
+TInt DPager::DiscardAndAllocPage(SPageInfo* aPageInfo, TZonePageType aPageType)
+ {
+ TInt r = DiscardPage(aPageInfo, KRamZoneInvalidId, EFalse);
+ if (r == KErrNone)
+ {
+ TheMmu.MarkPageAllocated(aPageInfo->PhysAddr(), aPageType);
+ }
+ // Flash the ram alloc lock as we may have had to write a page out to swap.
+ RamAllocLock::Unlock();
+ RamAllocLock::Lock();
+ return r;
+ }
+
+
static TBool DiscardCanStealPage(SPageInfo* aOldPageInfo, TBool aBlockRest)
{
// If the page is pinned or if the page is dirty and a general defrag is being performed then
@@ -1002,6 +1025,9 @@
__NK_ASSERT_DEBUG(iNumberOfFreePages>0);
--iNumberOfFreePages;
+ // The page must be unpaged, otherwise it wasn't successfully removed
+ // from the live list.
+ __NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
MmuLock::Unlock();
TPhysAddr pagePhys = aPageInfo.PhysAddr();
@@ -2068,6 +2094,7 @@
}
+// WARNING THIS METHOD MAY HOLD THE RAM ALLOC LOCK FOR EXCESSIVE PERIODS. DON'T USE THIS IN ANY PRODUCTION CODE.
void DPager::FlushAll()
{
NKern::ThreadEnterCS();
@@ -2108,7 +2135,9 @@
}
++pi;
if(((TUint)pi&(0xf<<KPageInfoShift))==0)
+ {
MmuLock::Flash(); // every 16 page infos
+ }
}
while(pi<piEnd);
}