os/kernelhwsrv/kerneltest/e32test/emul/t_emulex.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\emul\t_emulex.cpp
    15 // Test various things to do with exceptions on the emulator
    16 // 
    17 //
    18 
    19 #include <e32test.h>
    20 
    21 #define WIN32_LEAN_AND_MEAN
    22 #define _WIN32_WINNT 0x0400
    23 #include <windows.h>
    24 #include <winnt.h>
    25 
    26 #define TestSuccess(r) { TInt _r = (r); if (_r != KErrNone) { test.Printf(_L("Error code: %d"), _r); test(EFalse); } }
    27 
    28 // LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo);
    29 // PVOID AddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler);
    30 // ULONG RemoveVectoredExceptionHandler(PVOID Handler);
    31 
    32 typedef TInt (WINAPI TVectoredHandler)(PEXCEPTION_POINTERS aExceptionInfo);
    33 typedef TAny* (WINAPI TAddVectoredHandlerFunc)(TBool aFirstHandler, TVectoredHandler aHandler);
    34 typedef TUint (WINAPI TRemoveVectoredHandlerFunc)(TAny* aHandler);
    35 
    36 RTest test(_L("T_EMULEX"));
    37 
    38 const TInt KSpinIterations = 5000;
    39 
    40 TInt TestIterations = 500;
    41 volatile TInt ExceptionCount;
    42 volatile TInt SpinCount;
    43 TAddVectoredHandlerFunc* AddVEHFunc;
    44 TRemoveVectoredHandlerFunc* RemoveVEHFunc;
    45 
    46 TBool LookupVEHFunctions()
    47 //
    48 // Look up VEH functions, return EFalse if not supported
    49 //
    50 	{
    51 	HMODULE hLibrary = GetModuleHandleA("kernel32.dll");
    52 	test(hLibrary != NULL);
    53 
    54 	AddVEHFunc = (TAddVectoredHandlerFunc*)GetProcAddress(hLibrary, "AddVectoredExceptionHandler");
    55 	RemoveVEHFunc = (TRemoveVectoredHandlerFunc*)GetProcAddress(hLibrary, "RemoveVectoredExceptionHandler");
    56 
    57 	return AddVEHFunc && RemoveVEHFunc;
    58 	}
    59 
    60 TInt WINAPI VectoredHandler(PEXCEPTION_POINTERS /*ExceptionInfo*/)
    61 	{
    62 	for (TInt i = 0 ; i < KSpinIterations ; ++i)
    63 		++SpinCount; // spin 
    64 	return EXCEPTION_CONTINUE_SEARCH;
    65 	}
    66 
    67 TInt CppExceptionThreadFunction(TAny* /*aParam*/)
    68 	{
    69 	for (;;)
    70 		{
    71 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
    72 			++SpinCount; // spin
    73 		try
    74 			{
    75 			throw 23;
    76 			}
    77 		catch(TInt /*x*/)
    78 			{
    79 			++ExceptionCount;
    80 			}
    81 		}
    82 	}
    83 
    84 TInt CppExceptionThreadFunction2(TAny* /*aParam*/)
    85 	{
    86 	for (;;)
    87 		{
    88 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
    89 			++SpinCount; // spin
    90 		try
    91 			{
    92 			throw 23;
    93 			}
    94 		catch(TInt /*x*/)
    95 			{
    96 			User::Heap();
    97 			++ExceptionCount;
    98 			}
    99 		}
   100 	}
   101 
   102 void HwExceptionHandler(TExcType /*aType*/)
   103 	{
   104 	++ExceptionCount;
   105 	}
   106 
   107 TInt HwExceptionThreadFunction(TAny* /*aParam*/)
   108 	{
   109 	User::SetExceptionHandler(HwExceptionHandler, KExceptionInteger);
   110 
   111 	volatile int zero = 0, out;
   112 	for (;;)
   113 		{
   114 		for (TInt i = 0 ; i < KSpinIterations ; ++i)
   115 			++SpinCount; // spin
   116 		out = 1 / zero;
   117 		}
   118 	}
   119 
   120 void CreateTestThread(RThread& aThread, TThreadFunction aFunc)
   121 	{
   122 	TInt r = aThread.Create(_L("exceptionThread"),
   123 							aFunc,
   124 							KDefaultStackSize,
   125 							NULL,
   126 							NULL);
   127 	test(r == KErrNone);
   128 	}
   129 
   130 void Test1(TThreadFunction aFunc)
   131 	{
   132 	for (TInt i = 0 ; i < TestIterations ; ++i)
   133 		{
   134 		RThread thread;
   135 		CreateTestThread(thread, aFunc);
   136 		ExceptionCount = 0;
   137 		thread.SetPriority(EPriorityLess);
   138 		thread.Resume();
   139 		while (ExceptionCount == 0)
   140 			User::AfterHighRes(1);
   141 
   142 		test.Printf(_L("Iteration %d: ExceptionCount == %d\n"), i, ExceptionCount);
   143 
   144 		TRequestStatus status;
   145 		thread.Logon(status);
   146 		thread.Kill(KErrGeneral);
   147 		User::WaitForRequest(status);
   148 		CLOSE_AND_WAIT(thread);
   149 		}
   150 	}
   151 
   152 void Test2(TThreadFunction aFunc)
   153 	{
   154 	TAny* handle = (*AddVEHFunc)(ETrue, VectoredHandler);
   155 
   156 	RThread thread;
   157 	CreateTestThread(thread, aFunc);
   158 	ExceptionCount = 0;
   159 	SpinCount = 0;
   160 	thread.Resume();
   161 
   162 	for (TInt i = 0 ; i < TestIterations ; ++i)
   163 		{
   164 		ExceptionCount = 0;
   165 		thread.SetPriority(EPriorityNormal);
   166 		while (ExceptionCount == 0)
   167 			;
   168 		thread.SetPriority(EPriorityLess);
   169 		
   170 		test.Printf(_L("Iteration %d: ExceptionCount == %d\n"), i, ExceptionCount);
   171 
   172 		// test exception handling doesn't deadlock
   173 		try { throw 13; } catch (TInt /*x*/) { }
   174 		}
   175 
   176 	TRequestStatus status;
   177 	thread.Logon(status);
   178 	thread.Kill(KErrGeneral);
   179 	User::WaitForRequest(status);
   180 	CLOSE_AND_WAIT(thread);
   181 
   182 	(*RemoveVEHFunc)(handle);
   183 	}
   184 
   185 void ParseCommandLine()
   186 	{
   187 	TBuf<128> buf;
   188 	User::CommandLine(buf);
   189 	if (buf != KNullDesC)
   190 		{
   191 		TLex lex(buf);
   192 		lex.Val(TestIterations);
   193 		}
   194 	}
   195 
   196 TInt E32Main()
   197 	{
   198 	test.Title();
   199 	test.Start(_L("T_EMULEX"));
   200 
   201 	ParseCommandLine();
   202 
   203 	test.Next(_L("Test killing a thread while it's taking a hardware exception"));
   204 	Test1(HwExceptionThreadFunction);
   205 
   206 	test.Next(_L("Test killing a thread while it's taking a C++ exception"));
   207 	Test1(CppExceptionThreadFunction);
   208 
   209 	test.Next(_L("Test killing a thread while it's taking a C++ exception, and subsequently calling into the kernel"));
   210 	Test1(CppExceptionThreadFunction2);
   211 	
   212 	TBool vehSupported = LookupVEHFunctions();
   213 	if (vehSupported)
   214 		{
   215 		test.Next(_L("Test thread preemption while taking a hardware exception"));
   216 		Test2(HwExceptionThreadFunction);
   217 
   218 		test.Next(_L("Test thread preemption while taking a C++ exception"));
   219 		Test2(CppExceptionThreadFunction);
   220 		}
   221 		
   222 	test.End();
   223 	test.Close();
   224 	return(0);
   225 	}