90 +(4+KPtClusterSize-1)/KPtClusterSize // page table pages |
90 +(4+KPtClusterSize-1)/KPtClusterSize // page table pages |
91 +(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage; // page table info pages |
91 +(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage; // page table info pages |
92 |
92 |
93 #elif defined(__CPU_X86) |
93 #elif defined(__CPU_X86) |
94 |
94 |
95 /* Need at least 6 mapped pages to guarantee to be able to execute all ARM instructions, |
95 /* Need at least 6 mapped pages to guarantee to be able to execute all X86 instructions, |
96 plus enough pages for 6 page tables to map those pages, plus enough pages for the |
96 plus enough pages for 6 page tables to map those pages, plus enough pages for the |
97 page table info structures of those page tables. |
97 page table info structures of those page tables. |
98 (Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all |
98 (Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all |
99 straddling chunk boundaries.) |
99 straddling chunk boundaries.) |
100 */ |
100 */ |
198 // Allocate a single page |
198 // Allocate a single page |
199 TPhysAddr pagePhys; |
199 TPhysAddr pagePhys; |
200 TInt r = m.AllocRam(&pagePhys, 1, |
200 TInt r = m.AllocRam(&pagePhys, 1, |
201 (Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), |
201 (Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), |
202 EPageDiscard); |
202 EPageDiscard); |
203 if(r!=KErrNone) |
203 __NK_ASSERT_ALWAYS(r == KErrNone); |
204 __NK_ASSERT_ALWAYS(0); |
|
205 MmuLock::Lock(); |
204 MmuLock::Lock(); |
206 AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys)); |
205 AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys)); |
207 MmuLock::Unlock(); |
206 MmuLock::Unlock(); |
208 } |
207 } |
209 RamAllocLock::Unlock(); |
208 RamAllocLock::Unlock(); |
212 TRACEB(("DPager::InitCache() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount)); |
211 TRACEB(("DPager::InitCache() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount)); |
213 } |
212 } |
214 |
213 |
215 |
214 |
216 #ifdef _DEBUG |
215 #ifdef _DEBUG |
|
216 #ifdef FMM_PAGER_CHECK_LISTS |
|
217 TBool CheckList(SDblQueLink* aHead, TUint aCount) |
|
218 { |
|
219 SDblQueLink* link = aHead; |
|
220 while(aCount--) |
|
221 { |
|
222 link = link->iNext; |
|
223 if(link == aHead) |
|
224 return EFalse; |
|
225 } |
|
226 link = link->iNext; |
|
227 if(link != aHead) |
|
228 return EFalse; |
|
229 return ETrue; |
|
230 } |
|
231 #endif // #ifdef FMM_PAGER_CHECK_LISTS |
|
232 |
217 TBool DPager::CheckLists() |
233 TBool DPager::CheckLists() |
218 { |
234 { |
219 #if 0 |
235 #ifdef FMM_PAGER_CHECK_LISTS |
220 __NK_ASSERT_DEBUG(MmuLock::IsHeld()); |
236 __NK_ASSERT_DEBUG(MmuLock::IsHeld()); |
221 SDblQueLink* head = &iOldList.iA; |
237 if (!CheckList(&iOldList.iA, iOldCount)) |
222 TInt n = iOldCount; |
238 return EFalse; |
223 SDblQueLink* link = head; |
239 if (!CheckList(&iYoungList.iA, iYoungCount)) |
224 while(n--) |
240 return EFalse; |
225 { |
241 if (!CheckList(&iOldestCleanList.iA, iOldestCleanCount)) |
226 link = link->iNext; |
242 return EFalse; |
227 if(link==head) |
243 if (!CheckList(&iOldestDirtyList.iA, iOldestDirtyCount)) |
228 return false; |
244 return EFalse; |
229 } |
245 TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d", iYoungCount, iOldCount, |
230 link = link->iNext; |
246 iOldestCleanCount, iOldestDirtyCount, iNumberOfFreePages)); |
231 if(link!=head) |
247 TraceCounts(); |
232 return false; |
248 #endif // #ifdef FMM_PAGER_CHECK_LISTS |
233 |
|
234 head = &iYoungList.iA; |
|
235 n = iYoungCount; |
|
236 link = head; |
|
237 while(n--) |
|
238 { |
|
239 link = link->iNext; |
|
240 if(link==head) |
|
241 return false; |
|
242 } |
|
243 link = link->iNext; |
|
244 if(link!=head) |
|
245 return false; |
|
246 |
|
247 // TRACEP(("DP: y=%d o=%d f=%d",iYoungCount,iOldCount,iNumberOfFreePages)); |
|
248 #endif |
|
249 // TraceCounts(); |
|
250 return true; |
249 return true; |
251 } |
250 } |
252 |
251 |
253 void DPager::TraceCounts() |
252 void DPager::TraceCounts() |
254 { |
253 { |
255 TRACEP(("DP: y=%d o=%d f=%d min=%d max=%d ml=%d res=%d", |
254 TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d min=%d max=%d ml=%d res=%d", |
256 iYoungCount,iOldCount,iNumberOfFreePages,iMinimumPageCount, |
255 iYoungCount, iOldCount, iOldestCleanCount, iOldestDirtyCount, |
257 iMaximumPageCount,iMinimumPageLimit,iReservePageCount)); |
256 iNumberOfFreePages, iMinimumPageCount, iMaximumPageCount, |
258 } |
257 iMinimumPageLimit, iReservePageCount)); |
259 |
258 } |
260 #endif |
259 #endif //#ifdef _DEBUG |
261 |
260 |
262 |
261 |
263 TBool DPager::HaveTooManyPages() |
262 TBool DPager::HaveTooManyPages() |
264 { |
263 { |
265 __NK_ASSERT_DEBUG(RamAllocLock::IsHeld()); |
264 __NK_ASSERT_DEBUG(RamAllocLock::IsHeld()); |
1982 NKern::ThreadEnterCS(); |
1981 NKern::ThreadEnterCS(); |
1983 RamAllocLock::Lock(); |
1982 RamAllocLock::Lock(); |
1984 |
1983 |
1985 MmuLock::Lock(); |
1984 MmuLock::Lock(); |
1986 |
1985 |
1987 __NK_ASSERT_ALWAYS(iYoungOldRatio!=0); |
1986 __NK_ASSERT_ALWAYS(iYoungOldRatio); |
1988 |
1987 |
1989 // Make sure aMinimumPageCount is not less than absolute minimum we can cope with... |
1988 // Make sure aMinimumPageCount is not less than absolute minimum we can cope with... |
1990 iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio |
1989 iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio |
1991 + DPageReadRequest::ReservedPagesRequired(); |
1990 + DPageReadRequest::ReservedPagesRequired(); |
1992 if(iMinimumPageLimit<iAbsoluteMinPageCount) |
1991 if(iMinimumPageLimit<iAbsoluteMinPageCount) |
1995 aMinimumPageCount = iMinimumPageLimit+iReservePageCount; |
1994 aMinimumPageCount = iMinimumPageLimit+iReservePageCount; |
1996 if(aMaximumPageCount<aMinimumPageCount) |
1995 if(aMaximumPageCount<aMinimumPageCount) |
1997 aMaximumPageCount=aMinimumPageCount; |
1996 aMaximumPageCount=aMinimumPageCount; |
1998 |
1997 |
1999 // Increase iMaximumPageCount? |
1998 // Increase iMaximumPageCount? |
2000 TInt extra = aMaximumPageCount-iMaximumPageCount; |
1999 if(aMaximumPageCount > iMaximumPageCount) |
2001 if(extra>0) |
2000 iMaximumPageCount = aMaximumPageCount; |
2002 iMaximumPageCount += extra; |
|
2003 |
2001 |
2004 // Reduce iMinimumPageCount? |
2002 // Reduce iMinimumPageCount? |
2005 TInt spare = iMinimumPageCount-aMinimumPageCount; |
2003 TInt spare = iMinimumPageCount-aMinimumPageCount; |
2006 if(spare>0) |
2004 if(spare>0) |
2007 { |
2005 { |
2835 |
2833 |
2836 |
2834 |
2837 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize) |
2835 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize) |
2838 { |
2836 { |
2839 // TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize)); |
2837 // TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize)); |
2840 if(iLockedPageCount) |
2838 __NK_ASSERT_ALWAYS(!iLockedPageCount); // lock already used |
2841 __NK_ASSERT_ALWAYS(0); // lock already used |
|
2842 |
2839 |
2843 // calculate the number of pages that need to be locked... |
2840 // calculate the number of pages that need to be locked... |
2844 TUint mask=KPageMask; |
2841 TUint mask=KPageMask; |
2845 TUint offset=aStart&mask; |
2842 TUint offset=aStart&mask; |
2846 TInt numPages = (aSize+offset+mask)>>KPageShift; |
2843 TInt numPages = (aSize+offset+mask)>>KPageShift; |
2847 if(numPages>iMaxPageCount) |
2844 |
2848 __NK_ASSERT_ALWAYS(0); |
2845 // Should never be asked to lock more pages than are allocated to this object. |
|
2846 __NK_ASSERT_ALWAYS(numPages <= iMaxPageCount); |
2849 |
2847 |
2850 NKern::ThreadEnterCS(); |
2848 NKern::ThreadEnterCS(); |
2851 |
2849 |
2852 // find mapping which covers the specified region... |
2850 // find mapping which covers the specified region... |
2853 TUint offsetInMapping; |
2851 TUint offsetInMapping; |