kerneltest/e32test/mmu/t_cachechunk.cpp
changeset 201 43365a9b78a3
parent 152 657f875b013e
child 229 07a685bbdd3d
equal deleted inserted replaced
200:73ea206103e6 201:43365a9b78a3
    85 #include "mmudetect.h"
    85 #include "mmudetect.h"
    86 #include "d_memorytest.h"
    86 #include "d_memorytest.h"
    87 #include "d_gobble.h"
    87 #include "d_gobble.h"
    88 #include <dptest.h>
    88 #include <dptest.h>
    89 #include "freeram.h"
    89 #include "freeram.h"
    90 
    90 #include "..\demandpaging\t_dpcmn.h"
    91 LOCAL_D RTest test(_L("T_CACHECHUNK"));
    91 
       
    92 RTest test(_L("T_CACHECHUNK"));
    92 
    93 
    93 RMemoryTestLdd MemoryTest;
    94 RMemoryTestLdd MemoryTest;
    94 
    95 
    95 RChunk TestChunk;
    96 RChunk TestChunk;
    96 TUint8* TestChunkBase;
    97 TUint8* TestChunkBase;
   502 	r = TestChunk.Commit(0,min*2);
   503 	r = TestChunk.Commit(0,min*2);
   503 	test_KErrNone(r);
   504 	test_KErrNone(r);
   504 	}
   505 	}
   505 
   506 
   506 
   507 
       
   508 TBool StopCacheThreads;
       
   509 
       
   510 TInt CacheThreadFunc(TAny* aMax)
       
   511 	{
       
   512 	RThread::Rendezvous(KErrNone);
       
   513 	while (!StopCacheThreads)
       
   514 		{
       
   515 		TInt maxSize = (TInt)aMax;
       
   516 		TInt minSize;
       
   517 		TInt r = KErrNone;
       
   518 		for (minSize = PageSize << 4; r == KErrNone && !StopCacheThreads; minSize += PageSize)
       
   519 			{
       
   520 			r = UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
   521 			User::After(minSize/PageSize);
       
   522 			}
       
   523 		for (minSize -= PageSize; 
       
   524 			minSize > PageSize << 4 && r == KErrNone  && !StopCacheThreads;
       
   525 			minSize -= PageSize)
       
   526 			{
       
   527 			r = UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize,(TAny*)minSize,(TAny*)maxSize);
       
   528 			User::After(minSize/PageSize);
       
   529 			}
       
   530 		}
       
   531 	return KErrNone;
       
   532 	}
       
   533 
       
   534 
       
   535 TInt DonateThreadFunc(TAny*)
       
   536 	{
       
   537 	TChunkCreateInfo createInfo;
       
   538 	createInfo.SetCache(100 * PageSize);
       
   539 	RChunk chunk;
       
   540 	TInt r = chunk.Create(createInfo);
       
   541 	if (r != KErrNone)
       
   542 		{
       
   543 		RDebug::Printf("DonateThreadFunc: Failed to create cache chunk %d", r);
       
   544 		return r;
       
   545 		}
       
   546 	TUint chunkEnd = 0;
       
   547 	while (chunk.Commit(chunkEnd, PageSize) == KErrNone)
       
   548 		chunkEnd += PageSize;
       
   549 
       
   550 	RThread::Rendezvous(KErrNone);
       
   551 	while (!StopCacheThreads)
       
   552 		{
       
   553 		for (TUint i = PageSize; i <= chunkEnd && !StopCacheThreads; i += PageSize)
       
   554 			{
       
   555 			chunk.Unlock(0, i);
       
   556 			if (chunk.Lock(0, i) != KErrNone)
       
   557 				{// Recommit as many pages as possible.
       
   558 				while (chunk.Commit(0, chunkEnd) != KErrNone && !StopCacheThreads)
       
   559 					chunkEnd -= PageSize;
       
   560 				i = 0;
       
   561 				}
       
   562 			User::After(i/PageSize);
       
   563 			}
       
   564 		}
       
   565 	CLOSE_AND_WAIT(chunk);
       
   566 	return KErrNone;
       
   567 	}
       
   568 
       
   569 
       
   570 TInt DirtyThreadFunc(TAny*)
       
   571 	{
       
   572 	RThread::Rendezvous(KErrNone);
       
   573 
       
   574 	RChunk chunk;
       
   575 	TChunkCreateInfo createInfo;
       
   576 	createInfo.SetNormal(PageSize * 100, PageSize *100);
       
   577 	createInfo.SetPaging(TChunkCreateInfo::EPaged);
       
   578 	TInt r = chunk.Create(createInfo);
       
   579 	if (r != KErrNone)
       
   580 		{
       
   581 		RDebug::Printf("Failed to create a cache chunk %d", r);
       
   582 		return r;
       
   583 		}
       
   584 	TUint8* base = chunk.Base();
       
   585 	// Dirty each page in the chunk so that there are dirty pages in the live 
       
   586 	// list while it is being resized and pages are being unlocked.
       
   587 	while (!StopCacheThreads)
       
   588 		{
       
   589 		TUint8* p = base;
       
   590 		TUint8* pEnd = base + chunk.Size();
       
   591 		for (; p < pEnd && !StopCacheThreads; p += PageSize)
       
   592 			{
       
   593 			*p = (TUint8)(pEnd - p);
       
   594 			User::After((TUint8)(pEnd - p));
       
   595 			}
       
   596 		}
       
   597 	CLOSE_AND_WAIT(chunk);
       
   598 	return KErrNone;
       
   599 	}
       
   600 
       
   601 
       
   602 void TestResizeExcess()
       
   603 	{
       
   604 	test.Printf(_L("Commit all of memory again leaving 100 free pages\n"));
       
   605 	CommitEnd = 0;
       
   606 	TInt r;
       
   607 	while(KErrNone==(r=TestChunk.Commit(CommitEnd,PageSize)))
       
   608 		{
       
   609 		CommitEnd += PageSize;
       
   610 		}
       
   611 	test(r==KErrNoMemory);
       
   612 	test_KErrNone(TestChunk.Unlock(0, 100 * PageSize));
       
   613 
       
   614 	SVMCacheInfo info;
       
   615 	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetCacheSize, &info, 0));
       
   616 
       
   617 	StopCacheThreads = EFalse;
       
   618 	RThread cacheThread;
       
   619 	r = cacheThread.Create(	KNullDesC, CacheThreadFunc, KDefaultStackSize, PageSize,
       
   620 							PageSize, (TAny*)info.iMaxSize);
       
   621 	test_KErrNone(r);
       
   622 	TRequestStatus threadStarted;
       
   623 	cacheThread.Rendezvous(threadStarted);
       
   624 	TRequestStatus cacheStatus;
       
   625 	cacheThread.Logon(cacheStatus);
       
   626 	cacheThread.Resume();
       
   627 	User::WaitForRequest(threadStarted);
       
   628 	test_KErrNone(threadStarted.Int());
       
   629 
       
   630 	// Create the dirty thread before the donate thread as the donate thread may
       
   631 	// consume all the free ram periodically.
       
   632 	RThread dirtyThread;
       
   633 	r = dirtyThread.Create(KNullDesC, DirtyThreadFunc, KDefaultStackSize, PageSize, PageSize, NULL);
       
   634 	test_KErrNone(r);
       
   635 	dirtyThread.Rendezvous(threadStarted);
       
   636 	TRequestStatus dirtyStatus;
       
   637 	dirtyThread.Logon(dirtyStatus);
       
   638 	dirtyThread.Resume();
       
   639 	User::WaitForRequest(threadStarted);
       
   640 	test_KErrNone(threadStarted.Int());
       
   641 
       
   642 	RThread donateThread;
       
   643 	r = donateThread.Create(KNullDesC, DonateThreadFunc, KDefaultStackSize, PageSize, PageSize, NULL);
       
   644 	test_KErrNone(r);
       
   645 	donateThread.Rendezvous(threadStarted);
       
   646 	TRequestStatus donateStatus;
       
   647 	donateThread.Logon(donateStatus);
       
   648 	donateThread.Resume();
       
   649 	User::WaitForRequest(threadStarted);
       
   650 	test_KErrNone(threadStarted.Int());
       
   651 
       
   652 	// Run test for 10 secs.
       
   653 	User::After(10000000);
       
   654 
       
   655 	// End the test.
       
   656 	StopCacheThreads = ETrue;
       
   657 	User::WaitForRequest(donateStatus);
       
   658 	test_Equal(EExitKill, donateThread.ExitType());
       
   659 	test_KErrNone(donateThread.ExitReason());
       
   660 	User::WaitForRequest(dirtyStatus);
       
   661 	test_Equal(EExitKill, dirtyThread.ExitType());
       
   662 	test_KErrNone(dirtyThread.ExitReason());
       
   663 	User::WaitForRequest(cacheStatus);
       
   664 	test_Equal(EExitKill, cacheThread.ExitType());
       
   665 	test_KErrNone(cacheThread.ExitReason());
       
   666 
       
   667 	CLOSE_AND_WAIT(donateThread);
       
   668 	CLOSE_AND_WAIT(cacheThread);
       
   669 	CLOSE_AND_WAIT(dirtyThread);
       
   670 
       
   671 	test_KErrNone(UserSvr::HalFunction(	EHalGroupVM,
       
   672 										EVMHalSetCacheSize,
       
   673 										(TAny*)info.iMinSize,
       
   674 										(TAny*)info.iMaxSize));
       
   675 	}
       
   676 
   507 
   677 
   508 TInt E32Main()
   678 TInt E32Main()
   509 	{
   679 	{
   510 	test.Title();
   680 	test.Title();
   511 
   681 
   634 
   804 
   635 	// Restore original settings for live list size
   805 	// Restore original settings for live list size
   636 	if (resizeCache)
   806 	if (resizeCache)
   637 		test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax));
   807 		test_KErrNone(DPTest::SetCacheSize(originalMin, originalMax));
   638 
   808 
       
   809 	test_KErrNone(GetGlobalPolicies());
       
   810 	if (gDataPagingSupported)
       
   811 		{
       
   812 		test.Next(_L("Test interactions of chunk unlocking and page cache resizing"));
       
   813 		// Do this after the live list limit is restored.
       
   814 		test_KErrNone(TestChunk.Create(createInfo));
       
   815 		TestResizeExcess();
       
   816 		TestChunk.Close();
       
   817 		}
       
   818 
   639 	// end...
   819 	// end...
   640 	test.End();
   820 	test.End();
   641 	MemoryTest.Close();
   821 	MemoryTest.Close();
   642 	gobbler.Close();
   822 	gobbler.Close();
   643 	test.Close();
   823 	test.Close();