mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
Count only scheduled time when running performance tests
svn path=/trunk/; revision=16091
This commit is contained in:
parent
2caba7c355
commit
a5e4e00e8a
7 changed files with 219 additions and 71 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -14,3 +14,7 @@ _SetPriorityClass@8
|
|||
_SetThreadPriority@8
|
||||
_GetCurrentProcess@0
|
||||
_GetCurrentThread@0
|
||||
_GetThreadContext@8
|
||||
_SuspendThread@4
|
||||
_ResumeThread@4
|
||||
_Sleep@4
|
||||
|
|
|
@ -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(¤tContext, sizeof(CONTEXT));
|
||||
currentContext.ContextFlags = CONTEXT_FULL;
|
||||
|
||||
do {
|
||||
_Sleep(1);
|
||||
|
||||
if (_SuspendThread(hThread) == -1)
|
||||
break;
|
||||
|
||||
if (_GetThreadContext(hThread, ¤tContext) == 0)
|
||||
break;
|
||||
|
||||
if (IsContextChanged(¤tContext, &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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" );
|
||||
|
|
Loading…
Reference in a new issue