Update contrib.
     1 // Copyright (c) 2006-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".
 
     8 // Initial Contributors:
 
     9 // Nokia Corporation - initial contribution.
 
    14 // e32test\emul\t_emulex.cpp
 
    15 // Test various things to do with exceptions on the emulator
 
    21 #define WIN32_LEAN_AND_MEAN
 
    22 #define _WIN32_WINNT 0x0400
 
    26 #define TestSuccess(r) { TInt _r = (r); if (_r != KErrNone) { test.Printf(_L("Error code: %d"), _r); test(EFalse); } }
 
    28 // LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo);
 
    29 // PVOID AddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler);
 
    30 // ULONG RemoveVectoredExceptionHandler(PVOID Handler);
 
    32 typedef TInt (WINAPI TVectoredHandler)(PEXCEPTION_POINTERS aExceptionInfo);
 
    33 typedef TAny* (WINAPI TAddVectoredHandlerFunc)(TBool aFirstHandler, TVectoredHandler aHandler);
 
    34 typedef TUint (WINAPI TRemoveVectoredHandlerFunc)(TAny* aHandler);
 
    36 RTest test(_L("T_EMULEX"));
 
    38 const TInt KSpinIterations = 5000;
 
    40 TInt TestIterations = 500;
 
    41 volatile TInt ExceptionCount;
 
    42 volatile TInt SpinCount;
 
    43 TAddVectoredHandlerFunc* AddVEHFunc;
 
    44 TRemoveVectoredHandlerFunc* RemoveVEHFunc;
 
    46 TBool LookupVEHFunctions()
 
    48 // Look up VEH functions, return EFalse if not supported
 
    51 	HMODULE hLibrary = GetModuleHandleA("kernel32.dll");
 
    52 	test(hLibrary != NULL);
 
    54 	AddVEHFunc = (TAddVectoredHandlerFunc*)GetProcAddress(hLibrary, "AddVectoredExceptionHandler");
 
    55 	RemoveVEHFunc = (TRemoveVectoredHandlerFunc*)GetProcAddress(hLibrary, "RemoveVectoredExceptionHandler");
 
    57 	return AddVEHFunc && RemoveVEHFunc;
 
    60 TInt WINAPI VectoredHandler(PEXCEPTION_POINTERS /*ExceptionInfo*/)
 
    62 	for (TInt i = 0 ; i < KSpinIterations ; ++i)
 
    64 	return EXCEPTION_CONTINUE_SEARCH;
 
    67 TInt CppExceptionThreadFunction(TAny* /*aParam*/)
 
    71 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
 
    84 TInt CppExceptionThreadFunction2(TAny* /*aParam*/)
 
    88 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
 
   102 void HwExceptionHandler(TExcType /*aType*/)
 
   107 TInt HwExceptionThreadFunction(TAny* /*aParam*/)
 
   109 	User::SetExceptionHandler(HwExceptionHandler, KExceptionInteger);
 
   111 	volatile int zero = 0, out;
 
   114 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
 
   120 void CreateTestThread(RThread& aThread, TThreadFunction aFunc)
 
   122 	TInt r = aThread.Create(_L("exceptionThread"),
 
   130 void Test1(TThreadFunction aFunc)
 
   132 	for (TInt i = 0 ; i < TestIterations ; ++i)
 
   135 		CreateTestThread(thread, aFunc);
 
   137 		thread.SetPriority(EPriorityLess);
 
   139 		while (ExceptionCount == 0)
 
   140 			User::AfterHighRes(1);
 
   142 		test.Printf(_L("Iteration %d: ExceptionCount == %d\n"), i, ExceptionCount);
 
   144 		TRequestStatus status;
 
   145 		thread.Logon(status);
 
   146 		thread.Kill(KErrGeneral);
 
   147 		User::WaitForRequest(status);
 
   148 		CLOSE_AND_WAIT(thread);
 
   152 void Test2(TThreadFunction aFunc)
 
   154 	TAny* handle = (*AddVEHFunc)(ETrue, VectoredHandler);
 
   157 	CreateTestThread(thread, aFunc);
 
   162 	for (TInt i = 0 ; i < TestIterations ; ++i)
 
   165 		thread.SetPriority(EPriorityNormal);
 
   166 		while (ExceptionCount == 0)
 
   168 		thread.SetPriority(EPriorityLess);
 
   170 		test.Printf(_L("Iteration %d: ExceptionCount == %d\n"), i, ExceptionCount);
 
   172 		// test exception handling doesn't deadlock
 
   173 		try { throw 13; } catch (TInt /*x*/) { }
 
   176 	TRequestStatus status;
 
   177 	thread.Logon(status);
 
   178 	thread.Kill(KErrGeneral);
 
   179 	User::WaitForRequest(status);
 
   180 	CLOSE_AND_WAIT(thread);
 
   182 	(*RemoveVEHFunc)(handle);
 
   185 void ParseCommandLine()
 
   188 	User::CommandLine(buf);
 
   189 	if (buf != KNullDesC)
 
   192 		lex.Val(TestIterations);
 
   199 	test.Start(_L("T_EMULEX"));
 
   203 	test.Next(_L("Test killing a thread while it's taking a hardware exception"));
 
   204 	Test1(HwExceptionThreadFunction);
 
   206 	test.Next(_L("Test killing a thread while it's taking a C++ exception"));
 
   207 	Test1(CppExceptionThreadFunction);
 
   209 	test.Next(_L("Test killing a thread while it's taking a C++ exception, and subsequently calling into the kernel"));
 
   210 	Test1(CppExceptionThreadFunction2);
 
   212 	TBool vehSupported = LookupVEHFunctions();
 
   215 		test.Next(_L("Test thread preemption while taking a hardware exception"));
 
   216 		Test2(HwExceptionThreadFunction);
 
   218 		test.Next(_L("Test thread preemption while taking a C++ exception"));
 
   219 		Test2(CppExceptionThreadFunction);