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);