Count only scheduled time when running performance tests

svn path=/trunk/; revision=16091
This commit is contained in:
Casper Hornstrup 2005-06-19 12:41:22 +00:00
parent 2caba7c355
commit a5e4e00e8a
7 changed files with 219 additions and 71 deletions

View file

@ -98,3 +98,27 @@ _GetCurrentThread()
{
return GetCurrentThread();
}
BOOL STDCALL
_GetThreadContext(HANDLE hThread, LPCONTEXT lpContext)
{
return GetThreadContext(hThread, lpContext);
}
DWORD STDCALL
_SuspendThread(HANDLE hThread)
{
return SuspendThread(hThread);
}
DWORD STDCALL
_ResumeThread(HANDLE hThread)
{
return ResumeThread(hThread);
}
VOID STDCALL
_Sleep(DWORD dwMilliseconds)
{
return Sleep(dwMilliseconds);
}

View file

@ -14,3 +14,7 @@ _SetPriorityClass@8
_SetThreadPriority@8
_GetCurrentProcess@0
_GetCurrentThread@0
_GetThreadContext@8
_SuspendThread@4
_ResumeThread@4
_Sleep@4

View file

@ -24,6 +24,9 @@ typedef struct _PERFORM_TEST_ARGS
TestOutputRoutine OutputRoutine;
_PTEST Test;
LPSTR TestName;
DWORD Result;
char Buffer[5000];
DWORD Time;
} PERFORM_TEST_ARGS;
int _Result;
@ -38,10 +41,8 @@ InitializeTests()
}
char*
FormatExecutionTime(char *buffer, LPFILETIME time)
FormatExecutionTime(char *buffer, ULONG milliseconds)
{
ULONG milliseconds = time->dwLowDateTime / 10000;
sprintf(buffer,
"%ldms",
milliseconds);
@ -52,55 +53,147 @@ DWORD WINAPI
PerformTest(PVOID _arg)
{
PERFORM_TEST_ARGS *Args = (PERFORM_TEST_ARGS *)_arg;
TestOutputRoutine OutputRoutine = Args->OutputRoutine;
_PTEST Test = Args->Test;
LPSTR TestName = Args->TestName;
HANDLE hThread;
FILETIME time;
FILETIME ExecutionTime;
char OutputBuffer[5000];
char Buffer[5000];
char Format[100];
hThread = _GetCurrentThread();
_SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
_SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE);
memset(Buffer, 0, sizeof(Buffer));
memset(Args->Buffer, 0, sizeof(Args->Buffer));
_SEH_TRY {
_Result = TS_OK;
_Buffer = Buffer;
_Buffer = Args->Buffer;
(Test->Routine)(TESTCMD_RUN);
Args->Result = _Result;
} _SEH_HANDLE {
_Result = TS_FAILED;
sprintf(Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
Args->Result = TS_FAILED;
sprintf(Args->Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
} _SEH_END;
if (_Result == TS_OK)
{
if (!_GetThreadTimes(hThread,
&time,
&time,
&time,
&ExecutionTime))
{
ExecutionTime.dwLowDateTime = 0;
ExecutionTime.dwHighDateTime = 0;
return 1;
}
BOOL
IsContextChanged(LPCONTEXT context1, LPCONTEXT context2)
{
return memcmp(context1, context2, sizeof(CONTEXT)) != 0;
}
VOID
ControlNormalTest(HANDLE hThread,
PERFORM_TEST_ARGS *Args,
DWORD TimeOut)
{
FILETIME time;
FILETIME executionTime;
DWORD status;
status = _WaitForSingleObject(hThread, TimeOut);
if (status == WAIT_TIMEOUT)
{
_TerminateThread(hThread, 0);
Args->Result = TS_TIMEDOUT;
}
status = _GetThreadTimes(hThread,
&time,
&time,
&time,
&executionTime);
Args->Time = executionTime.dwLowDateTime / 10000;
}
VOID
ControlPerformanceTest(HANDLE hThread,
PERFORM_TEST_ARGS *Args,
DWORD TimeOut)
{
DWORD status;
CONTEXT lastContext;
CONTEXT currentContext;
ZeroMemory(&lastContext, sizeof(CONTEXT));
lastContext.ContextFlags = CONTEXT_FULL;
ZeroMemory(&currentContext, sizeof(CONTEXT));
currentContext.ContextFlags = CONTEXT_FULL;
do {
_Sleep(1);
if (_SuspendThread(hThread) == -1)
break;
if (_GetThreadContext(hThread, &currentContext) == 0)
break;
if (IsContextChanged(&currentContext, &lastContext))
Args->Time++;
if (_ResumeThread(hThread) == -1)
break;
if (Args->Time >= TimeOut)
{
_TerminateThread(hThread, 0);
Args->Result = TS_TIMEDOUT;
break;
}
status = _WaitForSingleObject(hThread, 0);
if (status == WAIT_OBJECT_0 || status == WAIT_FAILED)
break;
lastContext = currentContext;
} while (TRUE);
}
VOID
DisplayResult(PERFORM_TEST_ARGS* Args,
LPSTR OutputBuffer)
{
char Buffer[5000];
char Format[100];
if (Args->Result == TS_OK)
{
sprintf(OutputBuffer,
"[%s] Success [%s]\n",
TestName,
Args->TestName,
FormatExecutionTime(Format,
&ExecutionTime));
Args->Time));
}
else if (Args->Result == TS_TIMEDOUT)
{
sprintf(OutputBuffer,
"[%s] Timed out [%s]\n",
Args->TestName,
FormatExecutionTime(Format,
Args->Time));
}
else
sprintf(OutputBuffer, "[%s] Failed (%s)\n", TestName, Buffer);
sprintf(OutputBuffer, "[%s] Failed (%s)\n", Args->TestName, Buffer);
if (OutputRoutine != NULL)
(*OutputRoutine)(OutputBuffer);
if (Args->OutputRoutine != NULL)
(*Args->OutputRoutine)(OutputBuffer);
else
DbgPrint(OutputBuffer);
return 1;
}
VOID
ControlTest(HANDLE hThread,
PERFORM_TEST_ARGS *Args,
DWORD TestType,
DWORD TimeOut)
{
switch (TestType)
{
case TT_NORMAL:
ControlNormalTest(hThread, Args, TimeOut);
break;
case TT_PERFORMANCE:
ControlPerformanceTest(hThread, Args, TimeOut);
break;
default:
printf("Unknown test type %ld\n", TestType);
break;
}
}
VOID
@ -113,10 +206,12 @@ PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
HANDLE hThread;
char OutputBuffer[1024];
char Name[200];
DWORD TestType;
DWORD TimeOut;
Args.OutputRoutine = OutputRoutine;
Args.TestName = Name;
Args.Time = 0;
CurrentEntry = AllTests.Flink;
for (; CurrentEntry != &AllTests; CurrentEntry = NextEntry)
@ -141,6 +236,13 @@ PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
if ((TestName != NULL) && (_stricmp(Name, TestName) != 0))
continue;
TestType = TT_NORMAL;
_Result = TS_OK;
_Buffer = (char *)&TestType;
(Current->Routine)(TESTCMD_TESTTYPE);
if (_Result != TS_OK)
TestType = TT_NORMAL;
/* Get timeout for test */
TimeOut = 0;
_Result = TS_OK;
@ -149,32 +251,19 @@ PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
if (_Result != TS_OK || TimeOut == INFINITE)
TimeOut = 5000;
/* Run test in thread */
/* Run test in a separate thread */
hThread = _CreateThread(NULL, 0, PerformTest, (PVOID)&Args, 0, NULL);
if (hThread == NULL)
sprintf(OutputBuffer,
"[%s] Failed (CreateThread() failed: %d)\n",
Name, (unsigned int)_GetLastError());
else if (_WaitForSingleObject(hThread, TimeOut) == WAIT_TIMEOUT)
{
if (!_TerminateThread(hThread, 0))
sprintf(OutputBuffer,
"[%s] Failed (timed out after %dms; TerminateThread() failed: %d)\n",
Name, (int)TimeOut, (unsigned int)_GetLastError());
else
sprintf(OutputBuffer, "[%s] Failed (timed out after %dms)\n", Name, (int)TimeOut);
_CloseHandle(hThread);
printf("[%s] Failed (CreateThread() failed: %ld)\n",
Name,
_GetLastError());
Args.Result = TS_FAILED;
}
else
{
_CloseHandle(hThread);
continue;
}
ControlTest(hThread, &Args, TestType, TimeOut);
if (OutputRoutine != NULL)
(*OutputRoutine)(OutputBuffer);
else
DbgPrint(OutputBuffer);
DisplayResult(&Args, OutputBuffer);
}
}

View file

@ -16,10 +16,16 @@ void SetupOnce()
/* Valid values for Command parameter of TestRoutine */
#define TESTCMD_RUN 0 /* Buffer contains information about what failed */
#define TESTCMD_TESTNAME 1 /* Buffer contains description of test */
#define TESTCMD_TIMEOUT 2 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
#define TESTCMD_TESTTYPE 1 /* Buffer contains type of test */
#define TESTCMD_TESTNAME 2 /* Buffer contains description of test */
#define TESTCMD_TIMEOUT 3 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
/* Test types */
#define TT_NORMAL 0
#define TT_PERFORMANCE 1
/* Valid values for return values of TestRoutine */
#define TS_TIMEDOUT -2
#define TS_EXCEPTION -1
#define TS_OK 0
#define TS_FAILED 1
@ -28,7 +34,7 @@ extern int _Result;
extern char *_Buffer;
/* Macros to simplify tests */
#define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
#define _DispatcherTypeTimeout(FunctionName, TestName, TestType, TimeOut) \
void \
FunctionName(int Command) \
{ \
@ -37,6 +43,9 @@ FunctionName(int Command) \
case TESTCMD_RUN: \
RunTest(); \
break; \
case TESTCMD_TESTTYPE: \
*(PDWORD)_Buffer = (DWORD)TestType; \
break; \
case TESTCMD_TESTNAME: \
strcpy(_Buffer, TestName); \
break; \
@ -49,7 +58,14 @@ FunctionName(int Command) \
} \
}
#define _Dispatcher(FunctionName, TestName) _DispatcherTimeout(FunctionName, TestName, 5000)
#define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
_DispatcherTypeTimeout(FunctionName, TestName, TT_NORMAL, TimeOut)
#define _DispatcherType(FunctionName, TestName, TestType) \
_DispatcherTypeTimeout(FunctionName, TestName, TestType, 5000)
#define _Dispatcher(FunctionName, TestName) \
_DispatcherTimeout(FunctionName, TestName, 5000)
static inline void
AppendAssertion(char *message)
@ -211,6 +227,18 @@ _GetCurrentProcess();
HANDLE STDCALL
_GetCurrentThread();
BOOL STDCALL
_GetThreadContext(HANDLE hThread, LPCONTEXT lpContext);
DWORD STDCALL
_SuspendThread(HANDLE hThread);
DWORD STDCALL
_ResumeThread(HANDLE hThread);
VOID STDCALL
_Sleep(DWORD dwMilliseconds);
static inline PCHAR
FrameworkGetExportedFunctionNameInternal(_PAPI_DESCRIPTION ApiDescription)

View file

@ -136,6 +136,8 @@
<symbol>ObReferenceObjectByName@32</symbol>
<symbol>HalQueryDisplayOwnership@0</symbol>
<symbol>IoDeviceObjectType</symbol>
<symbol>@KfReleaseSpinLock@8</symbol>
<symbol>@KfAcquireSpinLock@4</symbol>
</component>
<component name="freetype.dll">
<symbol>FT_Init_FreeType</symbol>

View file

@ -31,7 +31,7 @@ static void RunTest()
UINT i;
SetupSurface(&surface, &rect);
for (i = 0; i < 1000; i++)
for (i = 0; i < 10000; i++)
{
BOOLEAN success = DIB_24BPP_ColorFill(&surface, &rect, color);
_AssertTrue(success);
@ -41,4 +41,4 @@ static void RunTest()
CleanupSurface(&surface);
}
_Dispatcher(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance")
_DispatcherType(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance", TT_PERFORMANCE)

View file

@ -364,7 +364,8 @@ TestSupportCode::WriteStartupFile ( Module& module )
s = s + sprintf ( s, " LPSTR lpszCmdParam,\n" );
s = s + sprintf ( s, " int nCmdShow)\n" );
s = s + sprintf ( s, "{\n" );
s = s + sprintf ( s, " _SetPriorityClass(_GetCurrentProcess(), IDLE_PRIORITY_CLASS);\n" );
s = s + sprintf ( s, " _SetPriorityClass(_GetCurrentProcess(), HIGH_PRIORITY_CLASS);\n" );
s = s + sprintf ( s, " _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);\n" );
s = s + sprintf ( s, " InitializeTests();\n" );
s = s + sprintf ( s, " RegisterTests();\n" );
s = s + sprintf ( s, " SetupOnce();\n" );