kerneltest/e32test/mmu/t_ramall.cpp
branchRCL_3
changeset 39 2bb754abd467
parent 28 5b5d147c7838
child 41 0ffb4e86fcc9
equal deleted inserted replaced
36:bbf8bed59bcb 39:2bb754abd467
    23 #include <e32hal.h>
    23 #include <e32hal.h>
    24 #include <dptest.h>
    24 #include <dptest.h>
    25 #include "d_shadow.h"
    25 #include "d_shadow.h"
    26 #include "mmudetect.h"
    26 #include "mmudetect.h"
    27 #include "freeram.h"
    27 #include "freeram.h"
       
    28 #include "d_gobble.h"
    28 
    29 
    29 LOCAL_D RTest test(_L("T_RAMALL"));
    30 LOCAL_D RTest test(_L("T_RAMALL"));
    30 
    31 
    31 _LIT(KLddFileName,"D_SHADOW.LDD");
    32 _LIT(KLddFileName,"D_SHADOW.LDD");
    32 
    33 
    44 TBool FragThreadStop;
    45 TBool FragThreadStop;
    45 TBool ManualTest;
    46 TBool ManualTest;
    46 TBool CacheSizeAdjustable;
    47 TBool CacheSizeAdjustable;
    47 TUint OrigMinCacheSize;
    48 TUint OrigMinCacheSize;
    48 TUint OrigMaxCacheSize;
    49 TUint OrigMaxCacheSize;
       
    50 
       
    51 //
       
    52 // Random number generation
       
    53 //
       
    54 
       
    55 TUint32 RandomSeed;
       
    56 
       
    57 TUint32 Random()
       
    58 	{
       
    59 	RandomSeed = RandomSeed*69069+1;
       
    60 	return RandomSeed;
       
    61 	}
       
    62 
       
    63 TUint32 Random(TUint32 aRange)
       
    64 	{
       
    65 	return (TUint32)((TUint64(Random())*TUint64(aRange))>>32);
       
    66 	}
       
    67 
       
    68 void RandomInit(TUint32 aSeed)
       
    69 	{
       
    70 	RandomSeed = aSeed+(aSeed<<8)+(aSeed<<16)+(aSeed<<24);
       
    71 	Random();
       
    72 	Random();
       
    73 	}
    49 
    74 
    50 TInt AllocPhysicalRam(TUint32& aAddr, TInt aSize, TInt aAlign)
    75 TInt AllocPhysicalRam(TUint32& aAddr, TInt aSize, TInt aAlign)
    51 	{
    76 	{
    52 	return Shadow.AllocPhysicalRam(aAddr,aSize,aAlign);
    77 	return Shadow.AllocPhysicalRam(aAddr,aSize,aAlign);
    53 	}
    78 	}
   142 	};
   167 	};
   143 
   168 
   144 
   169 
   145 TInt FillPhysicalRam(TAny* aArgs)
   170 TInt FillPhysicalRam(TAny* aArgs)
   146 	{
   171 	{
   147 	SPhysAllocData& allocData = *((SPhysAllocData*)aArgs);
   172 	SPhysAllocData allocData = *((SPhysAllocData*)aArgs);
   148 	TUint maxAllocs = FreeRam() / allocData.iSize;
   173 	TUint maxAllocs = FreeRam() / allocData.iSize;
   149 	TUint32* physAddrs = new TUint32[maxAllocs + 1];
   174 	TUint32* physAddrs = new TUint32[maxAllocs + 1];
   150 	if (!physAddrs)
   175 	if (!physAddrs)
   151 		return KErrNoMemory;
   176 		return KErrNoMemory;
   152 	TUint32* pa = physAddrs;
   177 	TUint32* pa = physAddrs;
   222 	TUint i = 0;
   247 	TUint i = 0;
   223 	for (; i < aNumThreads; i++)
   248 	for (; i < aNumThreads; i++)
   224 		{// Need enough heap to store addr of every possible allocation + 1.
   249 		{// Need enough heap to store addr of every possible allocation + 1.
   225 		TUint requiredHeapMax = Max(PageSize, ((TotalRam / aSize) * sizeof(TUint32)) + sizeof(TUint32));
   250 		TUint requiredHeapMax = Max(PageSize, ((TotalRam / aSize) * sizeof(TUint32)) + sizeof(TUint32));
   226 		TInt r = threads[i].Create(KNullDesC, FillPhysicalRam, KDefaultStackSize, PageSize, requiredHeapMax, (TAny*)&allocData);
   251 		TInt r = threads[i].Create(KNullDesC, FillPhysicalRam, KDefaultStackSize, PageSize, requiredHeapMax, (TAny*)&allocData);
   227 		test_KErrNone(r);
   252 		if (r != KErrNone)
       
   253 			break;			
   228 		threads[i].Logon(status[i]);
   254 		threads[i].Logon(status[i]);
   229 		}
   255 		}
   230 	for (i = 0; i < aNumThreads; i++)
   256 	TUint totalThreads = i;
       
   257 	for (i = 0; i < totalThreads; i++)
   231 		{
   258 		{
   232 		threads[i].Resume();
   259 		threads[i].Resume();
   233 		}
   260 		}
   234 	for (i = 0; i < aNumThreads; i++)
   261 	for (i = 0; i < totalThreads; i++)
   235 		{
   262 		{
   236 		User::WaitForRequest(status[i]);
   263 		User::WaitForRequest(status[i]);
   237 		test_Equal(EExitKill, threads[i].ExitType());
   264 		test_Equal(EExitKill, threads[i].ExitType());
   238 		TInt exitReason = threads[i].ExitReason();
   265 		TInt exitReason = threads[i].ExitReason();
   239 		test_Value(exitReason, exitReason >= 0 || exitReason == KErrNoMemory);
   266 		test_Value(exitReason, exitReason >= 0 || exitReason == KErrNoMemory);
   251 
   278 
   252 
   279 
   253 TInt TouchMemory(TAny*)
   280 TInt TouchMemory(TAny*)
   254 	{
   281 	{
   255 	RThread::Rendezvous(KErrNone);	// Signal that this thread has started running.
   282 	RThread::Rendezvous(KErrNone);	// Signal that this thread has started running.
       
   283 	RandomInit(TouchData.iSize);
   256 	while (!TouchDataStop)
   284 	while (!TouchDataStop)
   257 		{
   285 		{
   258 		TUint8* p = Chunk.Base();
   286 		TUint8* p = Chunk.Base();
   259 		TUint8* pEnd = p + ChunkCommitEnd;
   287 		TUint8* pEnd = p + ChunkCommitEnd;
   260 		TUint8* fragPEnd = p + TouchData.iFrequency;
   288 		TUint8* fragPEnd = p + TouchData.iFrequency;
   261 		for (TUint8* fragP = p + TouchData.iSize; fragPEnd < pEnd;)
   289 		for (TUint8* fragP = p + TouchData.iSize; fragPEnd < pEnd && !TouchDataStop;)
   262 			{
   290 			{
   263 			TUint8* data = fragP;
   291 			TUint8* data = fragP;
   264 			for (; data < fragPEnd; data += PageSize)
   292 			for (; data < fragPEnd && !TouchDataStop; data += PageSize)
   265 				{
   293 				{
   266 				*data = (TUint8)(data - fragP);
   294 				*data = (TUint8)(data - fragP);
       
   295 				TUint random = Random();
       
   296 				if (random & 0x8484)
       
   297 					User::After(random & 0xFFFF);
   267 				}
   298 				}
   268 			for (data = fragP; data < fragPEnd; data += PageSize)
   299 			for (data = fragP; data < fragPEnd && !TouchDataStop; data += PageSize)
   269 				{
   300 				{
   270 				if (*data != (TUint8)(data - fragP))
   301 				if (*data != (TUint8)(data - fragP))
   271 					{
   302 					{
   272 					RDebug::Printf("Error unexpected data 0x%x read from 0x%08x", *data, data);
   303 					RDebug::Printf("Error unexpected data 0x%x read from 0x%08x", *data, data);
   273 					return KErrGeneral;
   304 					return KErrGeneral;
   274 					}
   305 					}
       
   306 				TUint random = Random();
       
   307 				if (random & 0x8484)
       
   308 					User::After(random & 0xFFFF);
   275 				}
   309 				}
   276 			fragP = fragPEnd + TouchData.iSize;
   310 			fragP = fragPEnd + TouchData.iSize;
   277 			fragPEnd += TouchData.iFrequency;
   311 			fragPEnd += TouchData.iFrequency;
   278 			}
   312 			}
   279 		}
   313 		}
   309 
   343 
   310 	if (FragData.iDiscard && CacheSizeAdjustable && !FragThreadStop)
   344 	if (FragData.iDiscard && CacheSizeAdjustable && !FragThreadStop)
   311 		{
   345 		{
   312 		TUint minCacheSize = FreeRam();
   346 		TUint minCacheSize = FreeRam();
   313 		TUint maxCacheSize = minCacheSize;
   347 		TUint maxCacheSize = minCacheSize;
   314 		TUint currentCacheSize;
   348 		DPTest::SetCacheSize(minCacheSize, maxCacheSize);
   315 		test_KErrNone(DPTest::CacheSize(OrigMinCacheSize, OrigMaxCacheSize, currentCacheSize));
   349 		if (OrigMinCacheSize <= maxCacheSize)
   316 		test_KErrNone(DPTest::SetCacheSize(minCacheSize, maxCacheSize));
   350 			DPTest::SetCacheSize(OrigMinCacheSize, maxCacheSize);
   317 		test_KErrNone(DPTest::SetCacheSize(OrigMinCacheSize, maxCacheSize));
       
   318 		}
   351 		}
   319 	}
   352 	}
   320 
   353 
   321 
   354 
   322 void UnfragmentMemoryFunc()
   355 void UnfragmentMemoryFunc()
   323 	{
   356 	{
   324 	if (FragData.iDiscard && CacheSizeAdjustable)
   357 	if (FragData.iDiscard && CacheSizeAdjustable)
   325 		test_KErrNone(DPTest::SetCacheSize(OrigMinCacheSize, OrigMaxCacheSize));
   358 		DPTest::SetCacheSize(OrigMinCacheSize, OrigMaxCacheSize);
   326 	Chunk.Decommit(0, Chunk.MaxSize());
   359 	Chunk.Decommit(0, Chunk.MaxSize());
   327 	}
   360 	}
   328 
   361 
   329 
   362 
   330 TInt FragmentMemoryThreadFunc(TAny*)
   363 TInt FragmentMemoryThreadFunc(TAny*)
   349 	FragData.iFragThread = aFragThread;
   382 	FragData.iFragThread = aFragThread;
   350 
   383 
   351 	TChunkCreateInfo chunkInfo;
   384 	TChunkCreateInfo chunkInfo;
   352 	chunkInfo.SetDisconnected(0, 0, TotalRam);
   385 	chunkInfo.SetDisconnected(0, 0, TotalRam);
   353 	chunkInfo.SetPaging(TChunkCreateInfo::EUnpaged);
   386 	chunkInfo.SetPaging(TChunkCreateInfo::EUnpaged);
       
   387 	chunkInfo.SetClearByte(0x19);
   354 	test_KErrNone(Chunk.Create(chunkInfo));
   388 	test_KErrNone(Chunk.Create(chunkInfo));
   355 
   389 
   356 	if (aFragThread)
   390 	if (aFragThread)
   357 		{
   391 		{
   358 		TInt r = FragThread.Create(KNullDesC, FragmentMemoryThreadFunc, KDefaultStackSize, PageSize, PageSize, NULL);
   392 		TInt r = FragThread.Create(_L("FragThread"), FragmentMemoryThreadFunc, KDefaultStackSize, PageSize, PageSize, NULL);
   359 		test_KErrNone(r);
   393 		test_KErrNone(r);
   360 		FragThread.Logon(FragStatus);
   394 		FragThread.Logon(FragStatus);
   361 		FragThreadStop = EFalse;
   395 		FragThreadStop = EFalse;
   362 		TRequestStatus threadInitialised;
   396 		TRequestStatus threadInitialised;
   363 		FragThread.Rendezvous(threadInitialised);
   397 		FragThread.Rendezvous(threadInitialised);
   371 		}
   405 		}
   372 	if (aTouchMemory && !ManualTest)
   406 	if (aTouchMemory && !ManualTest)
   373 		{
   407 		{
   374 		TouchData.iSize = aSize;
   408 		TouchData.iSize = aSize;
   375 		TouchData.iFrequency = aFrequency;
   409 		TouchData.iFrequency = aFrequency;
   376 		TInt r = TouchThread.Create(KNullDesC, TouchMemory, KDefaultStackSize, PageSize, PageSize, NULL);
   410 		TInt r = TouchThread.Create(_L("TouchThread"), TouchMemory, KDefaultStackSize, PageSize, PageSize, NULL);
   377 		test_KErrNone(r);
   411 		test_KErrNone(r);
   378 		TouchThread.Logon(TouchStatus);
   412 		TouchThread.Logon(TouchStatus);
   379 		TouchDataStop = EFalse;
   413 		TouchDataStop = EFalse;
   380 		TRequestStatus threadInitialised;
   414 		TRequestStatus threadInitialised;
   381 		TouchThread.Rendezvous(threadInitialised);
   415 		TouchThread.Rendezvous(threadInitialised);
   405 		test_KErrNone(FragThread.ExitReason());
   439 		test_KErrNone(FragThread.ExitReason());
   406 		CLOSE_AND_WAIT(FragThread);
   440 		CLOSE_AND_WAIT(FragThread);
   407 		}
   441 		}
   408 	else
   442 	else
   409 		UnfragmentMemoryFunc();
   443 		UnfragmentMemoryFunc();
       
   444 	if (CacheSizeAdjustable)
       
   445 		test_KErrNone(DPTest::SetCacheSize(OrigMinCacheSize, OrigMaxCacheSize));
   410 	CLOSE_AND_WAIT(Chunk);
   446 	CLOSE_AND_WAIT(Chunk);
   411 	}
   447 	}
   412 
   448 
   413 
   449 
   414 void TestFillPhysicalRam(TUint aFragSize, TUint aFragFreq, TUint aAllocSize, TUint aAllocAlign, TBool aDiscard, TBool aTouchMemory)
   450 void TestFillPhysicalRam(TUint aFragSize, TUint aFragFreq, TUint aAllocSize, TUint aAllocAlign, TBool aDiscard, TBool aTouchMemory)
   416 	test.Printf(_L("TestFillPhysicalRam aFragSize 0x%x aFragFreq 0x%x aAllocSize 0x%x aAllocAlign %d dis %d touch %d\n"),
   452 	test.Printf(_L("TestFillPhysicalRam aFragSize 0x%x aFragFreq 0x%x aAllocSize 0x%x aAllocAlign %d dis %d touch %d\n"),
   417 				aFragSize, aFragFreq, aAllocSize, aAllocAlign, aDiscard, aTouchMemory);
   453 				aFragSize, aFragFreq, aAllocSize, aAllocAlign, aDiscard, aTouchMemory);
   418 	FragmentMemory(aFragSize, aFragFreq, aDiscard, aTouchMemory, EFalse);
   454 	FragmentMemory(aFragSize, aFragFreq, aDiscard, aTouchMemory, EFalse);
   419 	SPhysAllocData allocData;
   455 	SPhysAllocData allocData;
   420 	// Only check free all ram could be allocated in manual tests as fixed pages may be fragmented.
   456 	// Only check free all ram could be allocated in manual tests as fixed pages may be fragmented.
   421 	allocData.iCheckMaxAllocs = (ManualTest && !aTouchMemory && !aAllocAlign)? ETrue : EFalse;
   457 	allocData.iCheckMaxAllocs = (ManualTest && !aTouchMemory && !aAllocAlign);
   422 	allocData.iCheckFreeRam = ETrue;
   458 	allocData.iCheckFreeRam = ETrue;
   423 	allocData.iSize = aAllocSize;
   459 	allocData.iSize = aAllocSize;
   424 	allocData.iAlign = aAllocAlign;
   460 	allocData.iAlign = aAllocAlign;
   425 	TInt r = FillPhysicalRam(&allocData);
   461 	TInt r = FillPhysicalRam(&allocData);
   426 	test_Value(r, r >= 0);
   462 	test_Value(r, r >= 0);
   526 	test.Next(_L("TestClaimPhys"));
   562 	test.Next(_L("TestClaimPhys"));
   527 	TestClaimPhys();
   563 	TestClaimPhys();
   528 
   564 
   529 	if (memodel >= EMemModelTypeFlexible)
   565 	if (memodel >= EMemModelTypeFlexible)
   530 		{
   566 		{
       
   567 		// To stop these tests taking too long leave only 8MB of RAM free.
       
   568 		const TUint KFreePages = 2048;
       
   569 		test.Next(_L("Load gobbler LDD"));
       
   570 		TInt r = User::LoadLogicalDevice(KGobblerLddFileName);
       
   571 		test_Value(r, r == KErrNone || r == KErrAlreadyExists);
       
   572 		RGobbler gobbler;
       
   573 		r = gobbler.Open();
       
   574 		test_KErrNone(r);
       
   575 		TUint32 taken = gobbler.GobbleRAM(KFreePages * PageSize);
       
   576 		test.Printf(_L("Gobbled: %dK\n"), taken/1024);
       
   577 		test.Printf(_L("Free RAM 0x%08X bytes\n"),FreeRam());
       
   578 
   531 		test.Next(_L("TestFragmentedAllocation"));
   579 		test.Next(_L("TestFragmentedAllocation"));
   532 		TestFragmentedAllocation();
   580 		TestFragmentedAllocation();
   533 
   581 
   534 		test.Next(_L("TestMultipleContiguousAllocations"));
   582 		test.Next(_L("TestMultipleContiguousAllocations"));
   535 		TestMultipleContiguousAllocations(20, PageSize * 16, 0);
   583 		TestMultipleContiguousAllocations(20, PageSize * 16, 0);
   552 		UnfragmentMemory(ETrue, ETrue, EFalse);
   600 		UnfragmentMemory(ETrue, ETrue, EFalse);
   553 		FragmentMemory(PageSize * 32, PageSize * 64, ETrue, ETrue, EFalse);
   601 		FragmentMemory(PageSize * 32, PageSize * 64, ETrue, ETrue, EFalse);
   554 		TestMultipleContiguousAllocations(10, PageSize * 1024, PageShift + 10);
   602 		TestMultipleContiguousAllocations(10, PageSize * 1024, PageShift + 10);
   555 		UnfragmentMemory(ETrue, ETrue, EFalse);
   603 		UnfragmentMemory(ETrue, ETrue, EFalse);
   556 
   604 
       
   605 		// Temporarily disable these tests until errors they cause are fixed.
       
   606 #if 0
   557 		test.Next(_L("TestMultipleContiguousAllocations with repeated movable and discardable allocations"));
   607 		test.Next(_L("TestMultipleContiguousAllocations with repeated movable and discardable allocations"));
   558 		FragmentMemory(PageSize, PageSize * 2, EFalse, EFalse, ETrue);
   608 		FragmentMemory(PageSize, PageSize * 2, EFalse, EFalse, ETrue);
   559 		TestMultipleContiguousAllocations(20, PageSize * 2, PageShift);
   609 		TestMultipleContiguousAllocations(20, PageSize * 2, PageShift);
   560 		UnfragmentMemory(EFalse, EFalse, ETrue);
   610 		UnfragmentMemory(EFalse, EFalse, ETrue);
   561 		FragmentMemory(PageSize, PageSize * 2, EFalse, EFalse, ETrue);
   611 		FragmentMemory(PageSize, PageSize * 2, EFalse, EFalse, ETrue);
   568 		TestMultipleContiguousAllocations(20, PageSize * 512, PageShift + 8);
   618 		TestMultipleContiguousAllocations(20, PageSize * 512, PageShift + 8);
   569 		UnfragmentMemory(ETrue, EFalse, ETrue);
   619 		UnfragmentMemory(ETrue, EFalse, ETrue);
   570 		FragmentMemory(PageSize * 32, PageSize * 64, ETrue, EFalse, ETrue);
   620 		FragmentMemory(PageSize * 32, PageSize * 64, ETrue, EFalse, ETrue);
   571 		TestMultipleContiguousAllocations(20, PageSize * 1024, PageShift + 10);
   621 		TestMultipleContiguousAllocations(20, PageSize * 1024, PageShift + 10);
   572 		UnfragmentMemory(ETrue, EFalse, ETrue);
   622 		UnfragmentMemory(ETrue, EFalse, ETrue);
       
   623 #endif
       
   624 		gobbler.Close();
       
   625 		r = User::FreeLogicalDevice(KGobblerLddFileName);
       
   626 		test_KErrNone(r);
   573 		}
   627 		}
   574 
   628 
   575 	Shadow.Close();
   629 	Shadow.Close();
       
   630 	r = User::FreeLogicalDevice(KLddFileName);
       
   631 	test_KErrNone(r);
   576 	test.Printf(_L("Free RAM=%08x at end of test\n"),FreeRam());
   632 	test.Printf(_L("Free RAM=%08x at end of test\n"),FreeRam());
   577 	test.End();
   633 	test.End();
   578 	return(KErrNone);
   634 	return(KErrNone);
   579     }
   635     }