1289 TheDataPagedMemoryManager->Init3(); |
1289 TheDataPagedMemoryManager->Init3(); |
1290 TheCodePagedMemoryManager->Init3(); |
1290 TheCodePagedMemoryManager->Init3(); |
1291 TInt r = Kern::AddHalEntry(EHalGroupVM, VMHalFunction, 0); |
1291 TInt r = Kern::AddHalEntry(EHalGroupVM, VMHalFunction, 0); |
1292 __NK_ASSERT_ALWAYS(r==KErrNone); |
1292 __NK_ASSERT_ALWAYS(r==KErrNone); |
1293 PageCleaningLock::Init(); |
1293 PageCleaningLock::Init(); |
|
1294 #ifdef __DEMAND_PAGING_BENCHMARKS__ |
|
1295 for (TInt i = 0 ; i < EMaxPagingBm ; ++i) |
|
1296 ResetBenchmarkData((TPagingBenchmark)i); |
|
1297 #endif |
1294 } |
1298 } |
1295 |
1299 |
1296 |
1300 |
1297 void DPager::Fault(TFault aFault) |
1301 void DPager::Fault(TFault aFault) |
1298 { |
1302 { |
2119 TRACE(("DPager::FlushAll() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount)); |
2123 TRACE(("DPager::FlushAll() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount)); |
2120 |
2124 |
2121 PageCleaningLock::Unlock(); |
2125 PageCleaningLock::Unlock(); |
2122 RamAllocLock::Unlock(); |
2126 RamAllocLock::Unlock(); |
2123 NKern::ThreadLeaveCS(); |
2127 NKern::ThreadLeaveCS(); |
|
2128 } |
|
2129 |
|
2130 |
|
2131 TInt DPager::FlushRegion(DMemModelProcess* aProcess, TLinAddr aStartAddress, TUint aSize) |
|
2132 { |
|
2133 if (aSize == 0) |
|
2134 return KErrNone; |
|
2135 |
|
2136 // find mapping |
|
2137 NKern::ThreadEnterCS(); |
|
2138 TUint offsetInMapping; |
|
2139 TUint mapInstanceCount; |
|
2140 DMemoryMapping* mapping = MM::FindMappingInProcess(aProcess, aStartAddress, aSize, |
|
2141 offsetInMapping, mapInstanceCount); |
|
2142 if (!mapping) |
|
2143 { |
|
2144 NKern::ThreadLeaveCS(); |
|
2145 return KErrBadDescriptor; |
|
2146 } |
|
2147 |
|
2148 // check whether memory is demand paged |
|
2149 MmuLock::Lock(); |
|
2150 DMemoryObject* memory = mapping->Memory(); |
|
2151 if(mapInstanceCount != mapping->MapInstanceCount() || memory == NULL || !memory->IsDemandPaged()) |
|
2152 { |
|
2153 MmuLock::Unlock(); |
|
2154 mapping->Close(); |
|
2155 NKern::ThreadLeaveCS(); |
|
2156 return KErrNone; |
|
2157 } |
|
2158 |
|
2159 TRACE(("DPager::FlushRegion: %O %08x +%d", aProcess, aStartAddress, aSize)); |
|
2160 if (!K::Initialising) |
|
2161 TRACE2((" context %T %d", NCurrentThread(), NKern::CurrentContext())); |
|
2162 |
|
2163 // why did we not get assertion failures before I added this? |
|
2164 __NK_ASSERT_DEBUG(!Kern::CurrentThread().IsRealtime()); |
|
2165 |
|
2166 // acquire necessary locks |
|
2167 MmuLock::Unlock(); |
|
2168 RamAllocLock::Lock(); |
|
2169 PageCleaningLock::Lock(); |
|
2170 MmuLock::Lock(); |
|
2171 |
|
2172 // find region in memory object |
|
2173 TUint startPage = (offsetInMapping >> KPageShift) + mapping->iStartIndex; |
|
2174 TUint sizeInPages = ((aStartAddress & KPageMask) + aSize - 1) >> KPageShift; |
|
2175 TUint endPage = startPage + sizeInPages; |
|
2176 TRACE2(("DPager::FlushRegion: page range is %d to %d", startPage, endPage)); |
|
2177 |
|
2178 // attempt to flush each page |
|
2179 TUint index = startPage; |
|
2180 while (mapping->MapInstanceCount() == mapInstanceCount && |
|
2181 mapping->Memory() && index <= endPage) |
|
2182 { |
|
2183 TRACE2(("DPager::FlushRegion: flushing page %d", index)); |
|
2184 TPhysAddr physAddr = memory->iPages.PhysAddr(index); |
|
2185 |
|
2186 if (physAddr != KPhysAddrInvalid) |
|
2187 { |
|
2188 TRACE2(("DPager::FlushRegion: phys addr is %08x", physAddr)); |
|
2189 SPageInfo* pi = SPageInfo::SafeFromPhysAddr(physAddr); |
|
2190 if (pi) |
|
2191 { |
|
2192 __NK_ASSERT_DEBUG(pi->Type() == SPageInfo::EManaged); |
|
2193 SPageInfo::TPagedState state = pi->PagedState(); |
|
2194 if (state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld || |
|
2195 state==SPageInfo::EPagedOldestClean || state==SPageInfo::EPagedOldestDirty) |
|
2196 { |
|
2197 TRACE2(("DPager::FlushRegion: attempt to steal page")); |
|
2198 TInt r = StealPage(pi); |
|
2199 if(r==KErrNone) |
|
2200 { |
|
2201 TRACE2(("DPager::FlushRegion: attempt to page out %08x", physAddr)); |
|
2202 AddAsFreePage(pi); |
|
2203 TRACE2(("DPager::FlushRegion: paged out %08x", physAddr)); |
|
2204 } |
|
2205 else |
|
2206 TRACE2(("DPager::FlushRegion: page out %08x failed with %d", physAddr, r)); |
|
2207 } |
|
2208 } |
|
2209 } |
|
2210 |
|
2211 MmuLock::Flash(); |
|
2212 ++index; |
|
2213 } |
|
2214 |
|
2215 MmuLock::Unlock(); |
|
2216 PageCleaningLock::Unlock(); |
|
2217 RamAllocLock::Unlock(); |
|
2218 mapping->Close(); |
|
2219 NKern::ThreadLeaveCS(); |
|
2220 TRACE2(("DPager::FlushRegion: done")); |
|
2221 return KErrNone; |
2124 } |
2222 } |
2125 |
2223 |
2126 |
2224 |
2127 void DPager::GetLiveListInfo(SVMCacheInfo& aInfo) |
2225 void DPager::GetLiveListInfo(SVMCacheInfo& aInfo) |
2128 { |
2226 { |