kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
changeset 109 b3a1d9898418
parent 102 ef2a444a7410
child 152 657f875b013e
equal deleted inserted replaced
102:ef2a444a7410 109:b3a1d9898418
  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 	{