diff -r 2d65c2f76d7b -r 4a8fed1c0ef6 kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp --- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Tue Feb 02 01:24:03 2010 +0200 +++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Sat Feb 20 00:10:51 2010 +0200 @@ -50,14 +50,26 @@ DPager::DPager() : iMinimumPageCount(0), iMaximumPageCount(0), iYoungOldRatio(0), - iYoungCount(0),iOldCount(0),iNumberOfFreePages(0) + iYoungCount(0),iOldCount(0), +#ifdef _USE_OLDEST_LISTS + iOldestCleanCount(0), +#endif + iNumberOfFreePages(0), iReservePageCount(0), iMinimumPageLimit(0) { } -void DPager::Init2() +void DPager::InitCache() { - TRACEB(("DPager::Init2()")); + // + // This routine doesn't acquire any mutexes because it should be called before the system + // is fully up and running. I.e. called before another thread can preempt this. + // + TRACEB(("DPager::InitCache()")); + // If any pages have been reserved then they will have already been allocated and + // therefore should be counted as part of iMinimumPageCount. + __NK_ASSERT_DEBUG(iReservePageCount == iMinimumPageCount); + __NK_ASSERT_DEBUG(!CacheInitialised()); #if defined(__CPU_ARM) @@ -104,85 +116,92 @@ __NK_ASSERT_DEBUG(KMinOldPages<=iAbsoluteMinPageCount/2); - // initialise live list... - TUint minimumPageCount = 0; - TUint maximumPageCount = 0; - + // Read any paging config data. SDemandPagingConfig config = TheRomHeader().iDemandPagingConfig; - iMinimumPageCount = KDefaultMinPages; - if(minimumPageCount) - iMinimumPageCount = minimumPageCount; - if(config.iMinPages) - iMinimumPageCount = config.iMinPages; - if(iMinimumPageCount KAbsoluteMaxPageCount) - iMaximumPageCount = KAbsoluteMaxPageCount; - iInitMaximumPageCount = iMaximumPageCount; - + // Set the list ratios... iYoungOldRatio = KDefaultYoungOldRatio; if(config.iYoungOldRatio) iYoungOldRatio = config.iYoungOldRatio; - TInt ratioLimit = (iMinimumPageCount-KMinOldPages)/KMinOldPages; - if(iYoungOldRatio>ratioLimit) - iYoungOldRatio = ratioLimit; - #ifdef _USE_OLDEST_LISTS iOldOldestRatio = KDefaultOldOldestRatio; if(config.iSpare[2]) iOldOldestRatio = config.iSpare[2]; #endif - iMinimumPageLimit = (iMinYoungPages * (1 + iYoungOldRatio)) / iYoungOldRatio; - if(iMinimumPageLimit iMinimumPageCount) + iMinimumPageCount = iMinimumPageLimit + iReservePageCount; + + iInitMinimumPageCount = iMinimumPageCount; + + // Set the maximum page counts... + iMaximumPageCount = KMaxTInt; + if(config.iMaxPages) + iMaximumPageCount = config.iMaxPages; + if (iMaximumPageCount > KAbsoluteMaxPageCount) + iMaximumPageCount = KAbsoluteMaxPageCount; + iInitMaximumPageCount = iMaximumPageCount; + + + TRACEB(("DPager::InitCache() live list min=%d max=%d ratio=%d",iMinimumPageCount,iMaximumPageCount,iYoungOldRatio)); + + // Verify the page counts are valid. + __NK_ASSERT_ALWAYS(iMaximumPageCount >= iMinimumPageCount); TUint minOldAndOldest = iMinimumPageCount / (1 + iYoungOldRatio); - if(minOldAndOldest < KMinOldPages) - __NK_ASSERT_ALWAYS(0); - if (iMinimumPageCount < minOldAndOldest) - __NK_ASSERT_ALWAYS(0); + __NK_ASSERT_ALWAYS(minOldAndOldest >= KMinOldPages); + __NK_ASSERT_ALWAYS(iMinimumPageCount >= minOldAndOldest); + + // Need at least iMinYoungPages pages mapped to execute worst case CPU instruction TUint minYoung = iMinimumPageCount - minOldAndOldest; - if(minYoung < iMinYoungPages) - __NK_ASSERT_ALWAYS(0); // Need at least iMinYoungPages pages mapped to execute worst case CPU instruction + __NK_ASSERT_ALWAYS(minYoung >= iMinYoungPages); + + // Verify that the young old ratio can be met even when there is only the + // minimum number of old pages. + TInt ratioLimit = (iMinimumPageCount-KMinOldPages)/KMinOldPages; + __NK_ASSERT_ALWAYS(iYoungOldRatio <= ratioLimit); + #ifdef _USE_OLDEST_LISTS // There should always be enough old pages to allow the oldest lists ratio. TUint oldestCount = minOldAndOldest / (1 + iOldOldestRatio); - if (!oldestCount) - __NK_ASSERT_ALWAYS(0); + __NK_ASSERT_ALWAYS(oldestCount); #endif + iNumberOfFreePages = 0; iNumberOfDirtyPages = 0; - // Allocate RAM pages and put them all on the old list + // Allocate RAM pages and put them all on the old list. + // Reserved pages have already been allocated and already placed on the + // old list so don't allocate them again. RamAllocLock::Lock(); iYoungCount = 0; +#ifdef _USE_OLDEST_LISTS iOldCount = 0; -#ifdef _USE_OLDEST_LISTS - iOldestCleanCount = 0; iOldestDirtyCount = 0; + __NK_ASSERT_DEBUG(iOldestCleanCount == iReservePageCount); +#else + __NK_ASSERT_DEBUG(iOldCount == iReservePageCount); #endif Mmu& m = TheMmu; - for(TUint i=0; iiName,aDevice->iType)); + __NK_ASSERT_DEBUG(!ThePager.CacheInitialised()); __NK_ASSERT_ALWAYS(aDevice->iReadUnitShift <= KPageShift); TInt r = KErrNotSupported; // Will return this if unsupported device type is installed