kerneltest/e32test/demandpaging/t_threadcreate.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\demandpaging\t_threadcreate.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #define __E32TEST_EXTENSION__
       
    19 #include <e32test.h>
       
    20 #include <dptest.h>
       
    21 #include <e32hal.h>
       
    22 #include <u32exec.h>
       
    23 #include <e32svr.h>
       
    24 #include <e32panic.h>
       
    25 #include "u32std.h"
       
    26 
       
    27 #include "t_dpcmn.h"
       
    28 
       
    29 enum
       
    30 	{
       
    31 	EUnspecified, 
       
    32 	EPaged, 
       
    33 	EUnpaged,
       
    34 	};
       
    35 
       
    36 _LIT(KGlobalThreadName, "gThreadGlobal");
       
    37 
       
    38 RSemaphore gSem1;
       
    39 RSemaphore gSem2;
       
    40 TBool gStackPaged;
       
    41 TUint8* gStackPtr = NULL;
       
    42 
       
    43 struct SThreadPagedInfo
       
    44 	{
       
    45 	TBool iHeapPaged;
       
    46 	TBool iStackPaged;
       
    47 	};
       
    48 
       
    49 TUint8 ReadByte(volatile TUint8* aPtr)
       
    50 	{
       
    51 	return *aPtr;
       
    52 	}
       
    53 
       
    54 TInt TestThreadFunction(TAny* aPtr)
       
    55 	{
       
    56 	for (TInt i = 0; i<2; i++)
       
    57 		{
       
    58 		if (i == 1)
       
    59 			{
       
    60 			User::SetRealtimeState(User::ERealtimeStateOn);
       
    61 			RDebug::Printf("aPtr %x",aPtr);
       
    62 			ReadByte((TUint8*)aPtr);
       
    63 			}
       
    64 		}
       
    65 	return KErrNone;
       
    66 	}
       
    67 
       
    68 //
       
    69 // IsStackPaged
       
    70 //
       
    71 // Determine whether the stack is paged by flushing the cache and attempting
       
    72 // to read a byte that has been paged out
       
    73 //
       
    74 //
       
    75 TInt IsStackPaged(const TUint8* aPtr)
       
    76 	{
       
    77 	RThread thread;
       
    78 	TInt r;
       
    79 	r = thread.Create(KNullDesC, TestThreadFunction, 0x1000, NULL, (TAny*)aPtr);
       
    80 	if (r != KErrNone)
       
    81 		{
       
    82 		return r;
       
    83 		}
       
    84 
       
    85 	TRequestStatus status;
       
    86 	thread.Logon(status);
       
    87 	if(status.Int() != KRequestPending)
       
    88 		{
       
    89 		return KErrGeneral;
       
    90 		}
       
    91 	thread.Resume();
       
    92 	User::WaitForRequest(status);
       
    93 	if (thread.ExitType() == EExitPanic &&
       
    94 		thread.ExitCategory() == _L("KERN-EXEC") &&
       
    95 		thread.ExitReason() == EIllegalFunctionForRealtimeThread)
       
    96 		{
       
    97 		gStackPaged = ETrue;
       
    98 		}
       
    99 	else
       
   100 		{ 
       
   101 		r = thread.ExitReason();
       
   102 		if(r != KErrNone)
       
   103 			return r;
       
   104 
       
   105 		if (EExitKill != thread.ExitType())
       
   106 			return KErrGeneral;
       
   107 		gStackPaged = EFalse;
       
   108 		}	
       
   109 	thread.Close();
       
   110 	if (!gStackPaged)
       
   111 		{
       
   112 		RDebug::Printf("    %08x present", aPtr);
       
   113 		}
       
   114 	else
       
   115 		{
       
   116 		RDebug::Printf("    %08x not present", aPtr);
       
   117 		}
       
   118 	return r;
       
   119 	}
       
   120 
       
   121 /**
       
   122 Thread that just returns the data paging attributes of the thread.
       
   123 */
       
   124 TInt ThreadFunc(TAny* aThreadInfo)
       
   125 	{
       
   126 	SThreadPagedInfo& info = *(SThreadPagedInfo*)aThreadInfo;
       
   127 	RHeap& heap = User::Heap();
       
   128 	RChunk chunk;
       
   129 	chunk.SetHandle(heap.ChunkHandle());
       
   130 	info.iHeapPaged = chunk.IsPaged();
       
   131 	gStackPtr = (TUint8*)&chunk;
       
   132 	RDebug::Printf("&chunk %x",&chunk);
       
   133 	gSem1.Signal();
       
   134 	gSem2.Wait();
       
   135 	info.iStackPaged = gStackPaged;
       
   136 	return KErrNone;
       
   137 	}
       
   138 
       
   139 TInt DummyFunction(TAny*)
       
   140 	{
       
   141 	return KErrNone;
       
   142 	}
       
   143 
       
   144 TInt PanicThreadCreate(TAny* aCreateInfo)
       
   145 	{
       
   146 	RThread thread;
       
   147 	TThreadCreateInfo createInfo((*(TThreadCreateInfo*) aCreateInfo));
       
   148 	thread.Create(createInfo);
       
   149 	return KErrGeneral; // Should never reach here
       
   150 	}
       
   151 
       
   152 //
       
   153 // CheckHeapStackPaged
       
   154 //
       
   155 // Using the TThreadCreateInfo used to create the cheap, determine 
       
   156 // whether the stack and the heap are paged or not
       
   157 //
       
   158 //
       
   159 TInt CheckHeapStackPaged(TThreadCreateInfo& aCreateInfo, TInt aPaged, SThreadPagedInfo& aPagedInfo, TBool aUseProcessHeap = EFalse)
       
   160 	{
       
   161 	RThread thread;
       
   162 	TBool paged;
       
   163 	switch (aPaged)
       
   164 		{
       
   165 		case EUnspecified:
       
   166 			test.Printf(_L("Testing gProcessPaged\n"));
       
   167 			paged = gProcessPaged;
       
   168 			break;
       
   169 
       
   170 		case EPaged:
       
   171 			test.Printf(_L("Testing Paged\n"));
       
   172 			aCreateInfo.SetPaging(TThreadCreateInfo::EPaged);
       
   173 			paged = ETrue;
       
   174 			break;
       
   175 
       
   176 		case EUnpaged:
       
   177 			test.Printf(_L("Testing Unpaged\n"));
       
   178 			aCreateInfo.SetPaging(TThreadCreateInfo::EUnpaged);
       
   179 			paged = EFalse;
       
   180 			break;
       
   181 		}
       
   182 
       
   183 
       
   184 	test_KErrNone(thread.Create(aCreateInfo));
       
   185 	
       
   186 	// Disable JIT debugging.
       
   187 	TBool justInTime=User::JustInTime();
       
   188 	User::SetJustInTime(EFalse);
       
   189 
       
   190 	TRequestStatus status;
       
   191 	thread.Logon(status); 
       
   192 	
       
   193 	thread.Resume();
       
   194 	
       
   195 	gSem1.Wait();		
       
   196 	DPTest::FlushCache();
       
   197 	TInt r = IsStackPaged(gStackPtr);
       
   198 	test_KErrNone(r);
       
   199 	gSem2.Signal();
       
   200 
       
   201 	User::WaitForRequest(status);
       
   202 	test (EExitKill == thread.ExitType());
       
   203 	test(KErrNone == status.Int());
       
   204 	
       
   205 	test(KErrNone == thread.ExitReason());
       
   206 
       
   207 	if (thread.ExitType() == EExitPanic)
       
   208 		{
       
   209 		test(thread.ExitCategory()==_L("USER"));
       
   210 		}
       
   211 			
       
   212 	CLOSE_AND_WAIT(thread);
       
   213 
       
   214 	// Put JIT debugging back to previous status.
       
   215 	User::SetJustInTime(justInTime);
       
   216 
       
   217 	UpdatePaged(paged);
       
   218 	if (aUseProcessHeap)
       
   219 		{// If using existing thread heap, heap will take the process paging status
       
   220 		test_Equal(gProcessPaged, aPagedInfo.iHeapPaged);
       
   221 		}
       
   222 	else
       
   223 		{
       
   224 		test_Equal(paged, aPagedInfo.iHeapPaged);
       
   225 		}
       
   226 	test_Equal(paged, aPagedInfo.iStackPaged);
       
   227 	return KErrNone;
       
   228 	}
       
   229 
       
   230 //
       
   231 // TestThreadCreate
       
   232 //
       
   233 //----------------------------------------------------------------------------------------------
       
   234 //! @SYMTestCaseID			KBASE-T_THREADHEAPCREATE-xxxx
       
   235 //! @SYMTestType			UT
       
   236 //! @SYMPREQ				PREQ1954
       
   237 //! @SYMTestCaseDesc		TThreadCreateInfo tests
       
   238 //!							Verify the thread heap creation implementation
       
   239 //! @SYMTestActions	
       
   240 //! 1.	Call TThreadCreateInfo::TThreadCreateInfo() with valid parameters. 
       
   241 //! 	Following this call RThread::Create()
       
   242 //! 2.	Call TThreadCreateInfo::TThreadCreateInfo() with an invalid stack size. 
       
   243 //!		Following this call RThread::Create()
       
   244 //! 3.	Call TThreadCreateInfo::SetCreateHeap() with an invalid min heap size. 
       
   245 //!		Following this call RThread::Create()
       
   246 //! 4.	Call TThreadCreateInfo::SetCreateHeap() with an invalid max heap size. 
       
   247 //!		Following this call RThread::Create()
       
   248 //! 5.	Call TThreadCreateInfo::SetCreateHeap() with minHeapSize. > maxHeapSize 
       
   249 //!		Following this call RThread::Create()
       
   250 //! 6.	Call TThreadCreateInfo::SetUseHeap() specifying NULL. Following this call RThread::Create()
       
   251 //! 7.	Call TThreadCreateInfo::SetOwner() with aOwner set to EOwnerProcess. 
       
   252 //!		Following this call RThread::Create()
       
   253 //! 8.	Call TThreadCreateInfo::SetOwner() with aOwner set to EOwnerThread. 
       
   254 //!		Following this call RThread::Create()
       
   255 //! 9.	Call TThreadCreateInfo::SetPaging() with aPaging set to unspecified. 
       
   256 //!		Following this call RThread::Create() and check the paging status of the thread
       
   257 //! 10.	Call TThreadCreateInfo::SetPaging() with aPaging set to EPaged. 
       
   258 //!		Following this call RThread::Create() and check the paging status of the thread
       
   259 //! 11.	Call TThreadCreateInfo::SetPaging() with aPaging set to EUnpaged. 
       
   260 //!		Following this call RThread::Create() and check the paging status of the thread
       
   261 //!
       
   262 //! @SYMTestExpectedResults All tests should pass.
       
   263 //! @SYMTestPriority        High
       
   264 //! @SYMTestStatus          Implemented
       
   265 //----------------------------------------------------------------------------------------------
       
   266 void TestThreadCreate()
       
   267 	{
       
   268 	TInt r;
       
   269 	test.Start(_L("Test RThread::Create() (New Heap)"));
       
   270 		{
       
   271 		RThread thread;
       
   272 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize, NULL);
       
   273 		createInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
       
   274 		r = thread.Create(createInfo);
       
   275 		test_KErrNone(r);
       
   276 		test_KErrNone(TestThreadExit(thread, EExitKill, KErrNone));
       
   277 		thread.Close();
       
   278 		}
       
   279 
       
   280 	test.Next(_L("Test RThread::Create() - invalid stack size"));
       
   281 		{
       
   282 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, -1 , NULL);
       
   283 		createInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
       
   284 		
       
   285 		RThread threadPanic;
       
   286 		test_KErrNone(threadPanic.Create(_L("Panic UserHeap"), PanicThreadCreate, KDefaultStackSize, KMinHeapSize, 
       
   287 															KMinHeapSize,  (TAny*) &createInfo));
       
   288 		test_KErrNone(TestThreadExit(threadPanic, EExitPanic, EThrdStackSizeNegative));
       
   289 		}
       
   290 
       
   291 	test.Next(_L("Test RThread::Create() - invalid min heap size"));
       
   292 		{
       
   293 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize , NULL);
       
   294 		createInfo.SetCreateHeap(-1, KMinHeapSize);
       
   295 		
       
   296 		RThread threadPanic;
       
   297 		test_KErrNone(threadPanic.Create(_L("Panic UserHeap"), PanicThreadCreate, KDefaultStackSize, KMinHeapSize, 
       
   298 															KMinHeapSize,  (TAny*) &createInfo));
       
   299 
       
   300 		test_KErrNone(TestThreadExit(threadPanic, EExitPanic, EThrdHeapMinTooSmall));
       
   301 		}
       
   302 
       
   303 	test.Next(_L("Test RThread::Create() - invalid max heap size"));
       
   304 		{
       
   305 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize , NULL);
       
   306 		createInfo.SetCreateHeap(KMinHeapSize, -1);
       
   307 		
       
   308 		RThread threadPanic;
       
   309 		test_KErrNone(threadPanic.Create(_L("Panic UserHeap"), PanicThreadCreate, KDefaultStackSize, KMinHeapSize, 
       
   310 															KMinHeapSize,  (TAny*) &createInfo));
       
   311 
       
   312 		test_KErrNone(TestThreadExit(threadPanic, EExitPanic, EThrdHeapMaxLessThanMin));
       
   313 		}
       
   314 
       
   315 	test.Next(_L("Test RThread::Create() - min heap size > max heap size"));
       
   316 		{
       
   317 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize , NULL);
       
   318 		createInfo.SetCreateHeap(KMinHeapSize << 1, KMinHeapSize);
       
   319 		
       
   320 		RThread threadPanic;
       
   321 		test_KErrNone(threadPanic.Create(_L("Panic UserHeap"), PanicThreadCreate, KDefaultStackSize, KMinHeapSize, 
       
   322 															KMinHeapSize,  (TAny*) &createInfo));
       
   323 
       
   324 		test_KErrNone(TestThreadExit(threadPanic, EExitPanic, EThrdHeapMaxLessThanMin));
       
   325 		}
       
   326 
       
   327 	test.Next(_L("Test TThreadCreateInfo::SetUseHeap() "));
       
   328 		{
       
   329 		RThread thread;
       
   330 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize, NULL);
       
   331 		createInfo.SetUseHeap(NULL);
       
   332 		r = thread.Create(createInfo);
       
   333 		test_KErrNone(r);
       
   334 		test_KErrNone(TestThreadExit(thread, EExitKill, KErrNone));
       
   335 		thread.Close();
       
   336 		}
       
   337 
       
   338 	test.Next(_L("Test TThreadCreateInfo::SetOwner(EOwnerProcess) "));
       
   339 		{
       
   340 		RThread thread;
       
   341 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize, NULL);
       
   342 		createInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
       
   343 		createInfo.SetOwner(EOwnerProcess);
       
   344 		r = thread.Create(createInfo);
       
   345 		test_KErrNone(r);
       
   346 		test_KErrNone(TestThreadExit(thread, EExitKill, KErrNone));
       
   347 		thread.Close();
       
   348 		}
       
   349 
       
   350 
       
   351 	test.Next(_L("Test TThreadCreateInfo::SetOwner(EOwnerThread) "));
       
   352 		{
       
   353 		RThread thread;
       
   354 		TThreadCreateInfo createInfo(KGlobalThreadName, DummyFunction, KDefaultStackSize, NULL);
       
   355 		createInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
       
   356 		createInfo.SetOwner(EOwnerThread);
       
   357 		r = thread.Create(createInfo);
       
   358 		test_KErrNone(r);
       
   359 		test_KErrNone(TestThreadExit(thread, EExitKill, KErrNone));
       
   360 		thread.Close();
       
   361 		}
       
   362 
       
   363 
       
   364 
       
   365 	gSem1.CreateLocal(0);
       
   366 	gSem2.CreateLocal(0);
       
   367 	test.Next(_L("Test Thread paging (New Heap)"));
       
   368 		{		
       
   369 		TBool aPaged = gProcessPaged;
       
   370 		SThreadPagedInfo pagedInfo;
       
   371 		test.Printf(_L("Testing gProcessPaged: aPaged = %x\n"), aPaged);
       
   372 		TThreadCreateInfo createInfo(	KGlobalThreadName, ThreadFunc, KDefaultStackSize,
       
   373 										(TAny*)&pagedInfo);
       
   374 		createInfo.SetCreateHeap(KMinHeapSize, KMinHeapSize);
       
   375 		
       
   376 		test_KErrNone(CheckHeapStackPaged(createInfo, EUnspecified, pagedInfo));
       
   377 		test_KErrNone(CheckHeapStackPaged(createInfo, EPaged, pagedInfo));
       
   378 		test_KErrNone(CheckHeapStackPaged(createInfo, EUnpaged, pagedInfo));
       
   379 		}
       
   380 
       
   381 
       
   382 	test.Next(_L("Test RThread::Create() (Existing Heap)"));
       
   383 		{
       
   384 		SThreadPagedInfo pagedInfo;
       
   385 		TThreadCreateInfo createInfo(	KGlobalThreadName, ThreadFunc, KDefaultStackSize, 
       
   386 										(TAny*)&pagedInfo);
       
   387 		createInfo.SetUseHeap(NULL);
       
   388 		
       
   389 		test_KErrNone(CheckHeapStackPaged(createInfo, EUnspecified, pagedInfo, ETrue));
       
   390 		test_KErrNone(CheckHeapStackPaged(createInfo, EPaged, pagedInfo, ETrue));
       
   391 		test_KErrNone(CheckHeapStackPaged(createInfo, EUnpaged, pagedInfo, ETrue));
       
   392 		}
       
   393 	test.End();
       
   394 	}
       
   395 
       
   396 
       
   397 
       
   398 TInt TestingTThreadCreate()
       
   399 	{
       
   400 	test.Printf(_L("Test TThreadCreateInfo\n"));
       
   401 	TestThreadCreate();
       
   402 
       
   403 	return 0;
       
   404 	}