kerneltest/e32test/thread/t_thread.cpp
changeset 270 ea2cef07f9fe
parent 189 a5496987b1da
child 271 dc268b18d709
equal deleted inserted replaced
255:d45b74d3fb20 270:ea2cef07f9fe
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
   312 		return(KThreadReturnValue);
   312 		return(KThreadReturnValue);
   313 	User::After(500000);
   313 	User::After(500000);
   314 	return(KErrNone);
   314 	return(KErrNone);
   315 	}
   315 	}
   316 
   316 
   317 TInt StartInstructionThread(RThread& aT, const TDesC& aName, TInt aInstruction, TOwnerType aOwnerType, TRequestStatus* aL, TRequestStatus* aR)
   317 TInt StartInstructionThread(RThread& aT, const TDesC& aName, TInt aInstruction, RAllocator* aAllocator, TOwnerType aOwnerType, TRequestStatus* aL, TRequestStatus* aR)
   318 	{
   318 	{
   319 	TInt r = aT.Create(aName, &InstructionThread, KDefaultStackSize, KHeapSize, KHeapSize, (TAny*)aInstruction, aOwnerType);
   319 	TInt r;
       
   320 	
       
   321 	if (aAllocator == NULL)
       
   322 		{
       
   323 		r = aT.Create(aName, &InstructionThread, KDefaultStackSize, KHeapSize, KHeapSize, (TAny*)aInstruction, aOwnerType);
       
   324 		}
       
   325 	else
       
   326 		{
       
   327 		r = aT.Create(aName, &InstructionThread, KDefaultStackSize, aAllocator, (TAny*)aInstruction, aOwnerType);
       
   328 		}
       
   329 
   320 	if (r!=KErrNone)
   330 	if (r!=KErrNone)
   321 		return r;
   331 		return r;
       
   332 
   322 	if (aL)
   333 	if (aL)
   323 		{
   334 		{
   324 		aT.Logon(*aL);
   335 		aT.Logon(*aL);
   325 		TInt s = aL->Int();
   336 		TInt s = aL->Int();
   326 		test_Equal(s, KRequestPending);
   337 		test_Equal(s, KRequestPending);
   327 		}
   338 		}
       
   339 
   328 	if (aR)
   340 	if (aR)
   329 		{
   341 		{
   330 		aT.Rendezvous(*aR);
   342 		aT.Rendezvous(*aR);
   331 		TInt s = aR->Int();
   343 		TInt s = aR->Int();
   332 		test_Equal(s, KRequestPending);
   344 		test_Equal(s, KRequestPending);
   333 		aT.Resume();
   345 		aT.Resume();
   334 		User::WaitForRequest(*aR);
   346 		User::WaitForRequest(*aR);
   335 		s = aR->Int();
   347 		s = aR->Int();
   336 		test_KErrNone(s);
   348 		test_KErrNone(s);
   337 		}
   349 		}
       
   350 
   338 	return r;
   351 	return r;
   339 	}
   352 	}
   340 
   353 
   341 
   354 
   342 LOCAL_D TInt test4Thread(TAny *aSem)
   355 LOCAL_D TInt test4Thread(TAny *aSem)
   402 
   415 
   403 	test.Start(_L("Close without create"));
   416 	test.Start(_L("Close without create"));
   404 	thread.Close();
   417 	thread.Close();
   405 	
   418 	
   406 	test.Next(_L("Create ENormal"));
   419 	test.Next(_L("Create ENormal"));
   407 	r = StartInstructionThread(thread, _L("Thread"), ENormal, EOwnerProcess, 0, 0);
   420 	r = StartInstructionThread(thread, _L("Thread"), ENormal, NULL, EOwnerProcess, 0, 0);
   408 	test_KErrNone(r);
   421 	test_KErrNone(r);
   409 
   422 
   410 	test.Next(_L("Test priorities"));
   423 	test.Next(_L("Test priorities"));
   411 	test(thread.Priority()==EPriorityNormal);
   424 	test(thread.Priority()==EPriorityNormal);
   412 	thread.SetPriority(EPriorityRealTime);	// WINS will commute this to EPriorityMuchMore
   425 	thread.SetPriority(EPriorityRealTime);	// WINS will commute this to EPriorityMuchMore
   545 
   558 
   546 	test.Start(_L("Run thread 10 times"));
   559 	test.Start(_L("Run thread 10 times"));
   547 	for (TInt xx=0;xx<10;xx++)
   560 	for (TInt xx=0;xx<10;xx++)
   548 		{
   561 		{
   549 		test.Printf(_L("\r%02d"),xx);
   562 		test.Printf(_L("\r%02d"),xx);
   550 		r = StartInstructionThread(thread, _L("Thread1"), ENormal, anOwnerType, &stat, 0);
   563 		r = StartInstructionThread(thread, _L("Thread1"), ENormal, NULL, anOwnerType, &stat, 0);
   551 		test_KErrNone(r);
   564 		test_KErrNone(r);
   552 		thread.Resume();
   565 		thread.Resume();
   553 		User::WaitForRequest(stat);
   566 		User::WaitForRequest(stat);
   554 		CLOSE_AND_WAIT(thread);
   567 		CLOSE_AND_WAIT(thread);
   555 		}
   568 		}
   556 	test.Printf(_L("\n"));
   569 	test.Printf(_L("\n"));
   557 
   570 
   558 	test.Next(_L("Panic within thread"));
   571 	test.Next(_L("Panic within thread"));
   559 	r = StartInstructionThread(thread, _L("Thread2"), EInstrPanic, anOwnerType, &stat, 0);
   572 	r = StartInstructionThread(thread, _L("Thread2"), EInstrPanic, NULL, anOwnerType, &stat, 0);
   560 	test_KErrNone(r);
   573 	test_KErrNone(r);
   561 	test(thread.ExitType()==EExitPending);
   574 	test(thread.ExitType()==EExitPending);
   562 	thread.Resume();
   575 	thread.Resume();
   563 	User::WaitForRequest(stat);
   576 	User::WaitForRequest(stat);
   564 	test(thread.ExitCategory()==_L("Hello"));
   577 	test(thread.ExitCategory()==_L("Hello"));
   568 
   581 
   569 	test.Next(_L("Panic external to thread"));
   582 	test.Next(_L("Panic external to thread"));
   570 	TInt ijk;
   583 	TInt ijk;
   571 	TUint seed[2] = { 0xadf85458, 0 };
   584 	TUint seed[2] = { 0xadf85458, 0 };
   572 	TUint maxcount = 0;
   585 	TUint maxcount = 0;
       
   586 	RHeap* temporaryHeap = User::ChunkHeap(NULL, KHeapSize*8192, KHeapSize*8192);
       
   587 	test(temporaryHeap != NULL);
   573 	for (ijk=0; ijk<8192; ++ijk)
   588 	for (ijk=0; ijk<8192; ++ijk)
   574 		{
   589 		{
   575 		if (!(ijk&255))
   590 		if (!(ijk&255))
   576 			test.Printf(_L("%d\n"), ijk);
   591 			test.Printf(_L("%d\n"), ijk);
   577 		r = StartInstructionThread(thread, _L("Thread3"), EWait, anOwnerType, &stat, 0);
   592 
       
   593 		//
       
   594 		// For this test we need to use a temporary heap created in advance as we
       
   595 		// will be panicking the thread at any point during its creation and since
       
   596 		// the heap would have been allocated by the user side thread, it is
       
   597 		// possible that if we let it allocate its own heap, the kernel may not
       
   598 		// be able to close it in the temporary states of creation or when
       
   599 		// TLocalThreadData::DllSetTls() grabs a temporary handle on the heap.
       
   600 		// In those cases RTest::CloseHandleAndWaitForDestruction() would timeout
       
   601 		// and the test would fail.
       
   602 		//
       
   603 		// In addition, if we shared the creating thread's heap allocations may
       
   604 		// be left behind and cause the heap mark test to fail on this thread.
       
   605 		//
       
   606 		r = StartInstructionThread(thread, _L("Thread3"), EWait, temporaryHeap, anOwnerType, &stat, 0);
   578 		test_KErrNone(r);
   607 		test_KErrNone(r);
   579 		__e32_atomic_store_ord32(&IFLAG, 0);
   608 		__e32_atomic_store_ord32(&IFLAG, 0);
   580 		thread.Resume();
   609 		thread.Resume();
   581 		thread.SetPriority(EPriorityMore);
   610 		thread.SetPriority(EPriorityMore);
   582 		if (maxcount==0)
   611 		if (maxcount==0)
   602 		test(thread.ExitReason()==123);
   631 		test(thread.ExitReason()==123);
   603 		test(thread.ExitType()==EExitPanic);
   632 		test(thread.ExitType()==EExitPanic);
   604 		r = RTest::CloseHandleAndWaitForDestruction(thread);
   633 		r = RTest::CloseHandleAndWaitForDestruction(thread);
   605 		test_KErrNone(r);
   634 		test_KErrNone(r);
   606 		}
   635 		}
       
   636 	temporaryHeap->Close();
   607 	
   637 	
   608 	test.Next(_L("Internal exit"));
   638 	test.Next(_L("Internal exit"));
   609 	r = StartInstructionThread(thread, _L("Thread4"), ENormal, anOwnerType, &stat, 0);
   639 	r = StartInstructionThread(thread, _L("Thread4"), ENormal, NULL, anOwnerType, &stat, 0);
   610 	test_KErrNone(r);
   640 	test_KErrNone(r);
   611 	test(thread.ExitType()==EExitPending);
   641 	test(thread.ExitType()==EExitPending);
   612 	thread.Resume();
   642 	thread.Resume();
   613 	User::WaitForRequest(stat);
   643 	User::WaitForRequest(stat);
   614 	test(thread.ExitCategory()==_L("Kill"));
   644 	test(thread.ExitCategory()==_L("Kill"));
   615 	test(thread.ExitReason()==KThreadReturnValue);
   645 	test(thread.ExitReason()==KThreadReturnValue);
   616 	test(thread.ExitType()==EExitKill);
   646 	test(thread.ExitType()==EExitKill);
   617 	CLOSE_AND_WAIT(thread);
   647 	CLOSE_AND_WAIT(thread);
   618 
   648 
   619 	test.Next(_L("External terminate"));
   649 	test.Next(_L("External terminate"));
   620 	r = StartInstructionThread(thread, _L("Thread5"), EWait, anOwnerType, &stat, &rstat);
   650 	r = StartInstructionThread(thread, _L("Thread5"), EWait, NULL, anOwnerType, &stat, &rstat);
   621 	test_KErrNone(r);
   651 	test_KErrNone(r);
   622 	test.Next(_L("Terminate"));
   652 	test.Next(_L("Terminate"));
   623 	thread.Terminate(KTerminationReason);
   653 	thread.Terminate(KTerminationReason);
   624 	test.Next(_L("Wait"));
   654 	test.Next(_L("Wait"));
   625 	User::WaitForRequest(stat);
   655 	User::WaitForRequest(stat);
   628 	test(thread.ExitType()==EExitTerminate);
   658 	test(thread.ExitType()==EExitTerminate);
   629 	test.Next(_L("Close"));
   659 	test.Next(_L("Close"));
   630 	CLOSE_AND_WAIT(thread);
   660 	CLOSE_AND_WAIT(thread);
   631   
   661   
   632 	test.Next(_L("External kill"));
   662 	test.Next(_L("External kill"));
   633 	r = StartInstructionThread(thread, _L("Thread6"), EWait, anOwnerType, &stat, &rstat);
   663 	r = StartInstructionThread(thread, _L("Thread6"), EWait, NULL, anOwnerType, &stat, &rstat);
   634 	test_KErrNone(r);
   664 	test_KErrNone(r);
   635 	thread.Suspend();
   665 	thread.Suspend();
   636 	thread.Resume();
   666 	thread.Resume();
   637 	thread.Kill(KKillReason);
   667 	thread.Kill(KKillReason);
   638 	User::WaitForRequest(stat);
   668 	User::WaitForRequest(stat);