equal
deleted
inserted
replaced
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 } |