kerneltest/e32test/mmu/t_demandpaging.cpp
branchRCL_3
changeset 28 5b5d147c7838
parent 0 a41df078684a
child 43 c1f20ce4abcf
equal deleted inserted replaced
26:c734af59ce98 28:5b5d147c7838
   119 	return *aPtr;
   119 	return *aPtr;
   120 	}
   120 	}
   121 
   121 
   122 #define READ(a) ReadByte((volatile TUint8*)(a))
   122 #define READ(a) ReadByte((volatile TUint8*)(a))
   123 
   123 
   124 void ThrashPaging(TUint aMaxBytes=KMaxTUint)
   124 void ThrashPaging(TUint aBytes)
   125 	{
   125 	{
   126 	TUint size = LargeBufferSize;
   126 	TUint size = LargeBufferSize;
   127 	if(size>aMaxBytes)
   127 	if(size > aBytes)
   128 		size = aMaxBytes;
   128 		size = aBytes;
   129 
   129 
   130 	// read all ROM pages about 10 times each in a random order...
   130 	TUint readCount = 5 * size/PageSize;
       
   131 	
       
   132 	test.Printf(_L("ThrashPaging %u %u\n"), size, readCount);
       
   133 	
   131 	TUint32 random=1;
   134 	TUint32 random=1;
   132 	for(TInt i=size/(PageSize/10); i>0; --i)
   135 	for(TUint i = 0 ; i < readCount ; ++i)
   133 		{
   136 		{
   134 		READ(LargeBuffer+((TInt64(random)*TInt64(size))>>32));
   137 		READ(LargeBuffer+((TInt64(random)*TInt64(size))>>32));
   135 		random = random*69069+1;
   138 		random = random*69069+1;
   136 		}
   139 		}
   137 	}
   140 	}
   205 
   208 
   206 	test.End();
   209 	test.End();
   207 	}
   210 	}
   208 
   211 
   209 
   212 
       
   213 TInt SetCacheSize(TUint aNewMin, TUint aNewMax)
       
   214 	{
       
   215 	// set cache size and test 'get' function returns expected values
       
   216 	TInt r = DPTest::SetCacheSize(aNewMin, aNewMax);
       
   217 	if (r == KErrNone)
       
   218 		{
       
   219 		TUint min, max, current;
       
   220 		test_KErrNone(DPTest::CacheSize(min,max,current));
       
   221 		test_Equal(aNewMin, min);
       
   222 		test_Equal(aNewMax, max);
       
   223 		test(current >= min && current <= max);
       
   224 		}
       
   225 	return r;
       
   226 	}
       
   227 
       
   228 void DoResizeCache(TUint min, TUint max, TInt result, TUint& sizeMin, TUint& sizeMax, TUint originalMin, TUint originalMax)
       
   229 	{
       
   230 	test.Printf(_L("DPTest::SetCacheSize min=%u, max=%u, expected result=%d\n"),min/PageSize,max/PageSize,result);
       
   231 	TInt r=SetCacheSize(min,max);
       
   232 	test_Equal(result, r);
       
   233 	if(r==KErrNone)
       
   234 		{
       
   235 		// we've successfully changed the cache size...
       
   236 		if(max)
       
   237 			{
       
   238 			sizeMin = min;
       
   239 			sizeMax = max;
       
   240 			}
       
   241 		else
       
   242 			{
       
   243 			sizeMin = originalMin;
       
   244 			sizeMax = originalMax;
       
   245 			}
       
   246 		}
       
   247 	else if(r==KErrNoMemory)
       
   248 		{
       
   249 		// cache size after OOM is unpredictable, so reset our values
       
   250 		test_KErrNone(SetCacheSize(sizeMin,sizeMax));
       
   251 		}
       
   252 	}
       
   253 
       
   254 
   210 void TestResizeVMCache()
   255 void TestResizeVMCache()
   211 	{
   256 	{
       
   257 	test.Start(_L("Test resizing VM cache"));
   212 	TInt r = DPTest::SetCacheSize(0,0); // restore cache size to defaults
   258 	TInt r = DPTest::SetCacheSize(0,0); // restore cache size to defaults
   213 	test(r==KErrNone);
   259 	test(r==KErrNone);
   214 	TUint sizeMin = 0;
   260 	TUint sizeMin = 0;
   215 	TUint sizeMax = 0;
   261 	TUint sizeMax = 0;
   216 	TUint currentSize = 0;
   262 	TUint currentSize = 0;
   217 	DPTest::CacheSize(sizeMin,sizeMax,currentSize);
   263 	DPTest::CacheSize(sizeMin,sizeMax,currentSize);
   218 	TUint originalMin = sizeMin;
   264 	TUint originalMin = sizeMin;
   219 	TUint originalMax = sizeMax;
   265 	TUint originalMax = sizeMax;
   220 	test.Printf(_L("original min=%u, original max=%u, current=%u\n"),originalMin/PageSize,originalMax/PageSize,currentSize/PageSize);
   266 	test.Printf(_L("original min=%u, original max=%u, current=%u\n"),
       
   267 				originalMin/PageSize,originalMax/PageSize,currentSize/PageSize);
   221 
   268 
   222 	int K = currentSize/PageSize+4;
   269 	int K = currentSize/PageSize+4;
   223 
   270 
       
   271 	// Exercise the cache reszing code by testing all valid combinations of the relationships
       
   272 	// between the current min size, current max size, new min size and new max size.
       
   273 	//
       
   274 	// This can be done using four cache size values.  Every assignment of these four values to the
       
   275 	// four variables is generated, and invalid combinations rejected.  This repeats some
       
   276 	// relationships but is simpler than calculating the minimum set of combinations exactly.
       
   277 
       
   278 	const TUint combinations = 256;  // 4 ^ 4
       
   279 	const TUint sizes[] = { K, K + 4, K + 8, K + 12, K + 16 };
       
   280 	for (TUint perm = 0 ; perm < combinations ; ++perm)
       
   281 		{
       
   282 		TUint vars[4] = { sizes[ perm & 3 ],
       
   283 						  sizes[ (perm >> 2) & 3 ],
       
   284 						  sizes[ (perm >> 4) & 3 ],
       
   285 						  sizes[ (perm >> 6) & 3 ]};
       
   286 		if ((vars[0] == vars[2] && vars[1] == vars[3]) || // ensure current != new
       
   287 			vars[0] > vars[1] ||                          // ensure current min <= current max
       
   288 			vars[2] > vars[3])                            // ensure new min <= new max
       
   289 			continue;
       
   290 		
       
   291 		test.Printf(_L("Test changing cache sizes from %u, %u to %u %u\n"),
       
   292 					vars[0], vars[1], vars[2], vars[3]);
       
   293 		
       
   294 		test_KErrNone(SetCacheSize(PageSize * vars[0], PageSize * vars[1]));
       
   295 		ThrashPaging(PageSize * vars[1]);
       
   296 		test_KErrNone(SetCacheSize(PageSize * vars[2], PageSize * vars[3]));
       
   297 		}
       
   298 	test_KErrNone(SetCacheSize(originalMin, originalMax));
       
   299 
       
   300 	// Now test some more specific resizings
       
   301 	
   224 	struct
   302 	struct
   225 		{
   303 		{
   226 		TUint iMinPages;
   304 		TUint iMinPages;
   227 		TUint iMaxPages;
   305 		TUint iMaxPages;
   228 		TInt iResult;
   306 		TInt iResult;
   238 			{	K,		K,		KErrNone},
   316 			{	K,		K,		KErrNone},
   239 			{	K,		K+1,	KErrNone},
   317 			{	K,		K+1,	KErrNone},
   240 			{	K,		K,		KErrNone},
   318 			{	K,		K,		KErrNone},
   241 			{	K+1,	K,		KErrArgument},
   319 			{	K+1,	K,		KErrArgument},
   242 			{	K,		K-1,	KErrArgument},
   320 			{	K,		K-1,	KErrArgument},
       
   321 			{	K,		K,		KErrNone},
   243 			{	KMaxTInt,	KMaxTInt,	KErrNoMemory},
   322 			{	KMaxTInt,	KMaxTInt,	KErrNoMemory},
   244 			{	K,		K,		KErrNone},
   323 			{	K,		K,		KErrNone},
   245 
   324 
   246 			{	0,		0,		KErrNone}, // restore defaults
       
   247 			{	0,		0,		KMaxTInt} // list end marker
   325 			{	0,		0,		KMaxTInt} // list end marker
   248 		};
   326 		};
   249 
   327 
   250 	for(TInt j=0; j<2; ++j)
   328 	for(TInt j=0; j<2; ++j)
   251 		{
   329 		{
   252 		if(!j)
   330 		if(!j)
   253 			{
   331 			test.Next(_L("Changing size of empty VM cache"));
   254 			test.Start(_L("Changing size of flushed VM cache"));
       
   255 			test.Printf(_L("Original cache size min == %u, max == %u\n"),originalMin/PageSize,originalMax/PageSize);
       
   256 			}
       
   257 		else
   332 		else
   258 			test.Next(_L("Changing size of full VM cache"));
   333 			test.Next(_L("Changing size of full VM cache"));
       
   334 		
   259 		TInt i=0;
   335 		TInt i=0;
   260 		while(testArgs[i].iResult!=KMaxTInt)
   336 		while(testArgs[i].iResult!=KMaxTInt)
   261 			{
   337 			{
   262 			TUint min=testArgs[i].iMinPages*PageSize;
   338 			TUint min=testArgs[i].iMinPages*PageSize;
   263 			TUint max=testArgs[i].iMaxPages*PageSize;
   339 			TUint max=testArgs[i].iMaxPages*PageSize;
   264 			TInt result=testArgs[i].iResult;
   340 			TInt result=testArgs[i].iResult;
   265 
   341 
   266 			ThrashPaging(max*2);
       
   267 			if(!j)
   342 			if(!j)
   268 				DPTest::FlushCache();
   343 				DPTest::FlushCache();
   269 
       
   270 			test.Printf(_L("DPTest::SetCacheSize min=%u, max=%u, expected result=%d\n"),min/PageSize,max/PageSize,result);
       
   271 			TInt r=DPTest::SetCacheSize(min,max);
       
   272 			if(r!=result)
       
   273 				{
       
   274 				test.Printf(_L("result=%d\n"),r);
       
   275 				test(0);
       
   276 				}
       
   277 			if(r==KErrNone)
       
   278 				{
       
   279 				// we've successfully changed the cache size...
       
   280 				if(max)
       
   281 					{
       
   282 					sizeMin = min;
       
   283 					sizeMax = max;
       
   284 					}
       
   285 				else
       
   286 					{
       
   287 					sizeMin = originalMin;
       
   288 					sizeMax = originalMax;
       
   289 					}
       
   290 				}
       
   291 			if(r==KErrNoMemory)
       
   292 				{
       
   293 				// cache size after OOM is unpredictable, so reset our values
       
   294 				DPTest::SetCacheSize(sizeMin,sizeMax);
       
   295 				}
       
   296 			else
   344 			else
   297 				{
   345 				ThrashPaging(max);
   298 				// test 'get' function returns expected cache size
   346 
   299 				r=DPTest::CacheSize(min,max,currentSize);
   347 			DoResizeCache(min, max, result, sizeMin, sizeMax, originalMin, originalMax);
   300 				test.Printf(_L("DPTest::CacheSize result=%d min=%u max=%u current=%u\n"),r,min/PageSize,max/PageSize,currentSize/PageSize);
   348 			
   301 				if(r!=KErrNone || min!=sizeMin || max!=sizeMax)
       
   302 					test(0);
       
   303 				test(currentSize >= min && currentSize <= max);
       
   304 				}
       
   305 			++i;
   349 			++i;
   306 			}
   350 			}
   307 		}
   351 		}
   308 
   352 	
       
   353 	test_KErrNone(SetCacheSize(originalMin, originalMax));
   309 	test.End();
   354 	test.End();
   310 	}
   355 	}
   311 
       
   312 
       
   313 
   356 
   314 void TestResizeVMCache2()
   357 void TestResizeVMCache2()
   315 	{
   358 	{
   316 	TUint originalMin = 0;
   359 	TUint originalMin = 0;
   317 	TUint originalMax = 0;
   360 	TUint originalMax = 0;
  1238 TInt E32Main()
  1281 TInt E32Main()
  1239 	{
  1282 	{
  1240 	test.Title();
  1283 	test.Title();
  1241 	
  1284 	
  1242 	test_KErrNone(UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&PageSize,0));
  1285 	test_KErrNone(UserSvr::HalFunction(EHalGroupKernel,EKernelHalPageSizeInBytes,&PageSize,0));
       
  1286 
       
  1287 	test.Start(_L("Initialisation"));
  1243 	
  1288 	
  1244 	if (DPTest::Attributes() & DPTest::ERomPaging)
  1289 	if (DPTest::Attributes() & DPTest::ERomPaging)
  1245 		test.Printf(_L("Rom paging supported\n"));
  1290 		test.Printf(_L("Rom paging supported\n"));
  1246 	if (DPTest::Attributes() & DPTest::ECodePaging)
  1291 	if (DPTest::Attributes() & DPTest::ECodePaging)
  1247 		test.Printf(_L("Code paging supported\n"));
  1292 		test.Printf(_L("Code paging supported\n"));
  1256 		createInfo.SetGlobal(KChunkName);
  1301 		createInfo.SetGlobal(KChunkName);
  1257 		test_KErrNone(DataPagedChunk.Create(createInfo));
  1302 		test_KErrNone(DataPagedChunk.Create(createInfo));
  1258 		test(DataPagedChunk.IsPaged()); // this is only ever called if data paging is supported
  1303 		test(DataPagedChunk.IsPaged()); // this is only ever called if data paging is supported
  1259 		DataPagedBuffer = (TUint8*)DataPagedChunk.Base();
  1304 		DataPagedBuffer = (TUint8*)DataPagedChunk.Base();
  1260 		}
  1305 		}
  1261 		
       
  1262 	test.Start(_L("Test HAL interface"));
       
  1263 	TestHAL();
       
  1264 
  1306 
  1265 	if (DPTest::Attributes() & DPTest::ERomPaging)
  1307 	if (DPTest::Attributes() & DPTest::ERomPaging)
  1266 		{
  1308 		{
  1267 		// Use paged part of rom for testing
  1309 		// Use paged part of rom for testing
  1268 		TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  1310 		TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
  1300 		{
  1342 		{
  1301 		test.Printf(_L("Demand Paging not supported\n"));
  1343 		test.Printf(_L("Demand Paging not supported\n"));
  1302 		test.End();
  1344 		test.End();
  1303 		return 0;
  1345 		return 0;
  1304 		}
  1346 		}
       
  1347 		
       
  1348 	test.Next(_L("Test HAL interface"));
       
  1349 	TestHAL();
  1305 	
  1350 	
  1306 	test(LargeBufferSize >= KMinBufferSize);
  1351 	test(LargeBufferSize >= KMinBufferSize);
  1307 	SmallBuffer = LargeBuffer;
  1352 	SmallBuffer = LargeBuffer;
  1308 	SmallBufferSize = KMinBufferSize;
  1353 	SmallBufferSize = KMinBufferSize;
  1309 
  1354