mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +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();
|
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
|
_SetThreadPriority@8
|
||||||
_GetCurrentProcess@0
|
_GetCurrentProcess@0
|
||||||
_GetCurrentThread@0
|
_GetCurrentThread@0
|
||||||
|
_GetThreadContext@8
|
||||||
|
_SuspendThread@4
|
||||||
|
_ResumeThread@4
|
||||||
|
_Sleep@4
|
||||||
|
|
|
@ -24,6 +24,9 @@ typedef struct _PERFORM_TEST_ARGS
|
||||||
TestOutputRoutine OutputRoutine;
|
TestOutputRoutine OutputRoutine;
|
||||||
_PTEST Test;
|
_PTEST Test;
|
||||||
LPSTR TestName;
|
LPSTR TestName;
|
||||||
|
DWORD Result;
|
||||||
|
char Buffer[5000];
|
||||||
|
DWORD Time;
|
||||||
} PERFORM_TEST_ARGS;
|
} PERFORM_TEST_ARGS;
|
||||||
|
|
||||||
int _Result;
|
int _Result;
|
||||||
|
@ -38,13 +41,11 @@ InitializeTests()
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
FormatExecutionTime(char *buffer, LPFILETIME time)
|
FormatExecutionTime(char *buffer, ULONG milliseconds)
|
||||||
{
|
{
|
||||||
ULONG milliseconds = time->dwLowDateTime / 10000;
|
|
||||||
|
|
||||||
sprintf(buffer,
|
sprintf(buffer,
|
||||||
"%ldms",
|
"%ldms",
|
||||||
milliseconds);
|
milliseconds);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,55 +53,147 @@ DWORD WINAPI
|
||||||
PerformTest(PVOID _arg)
|
PerformTest(PVOID _arg)
|
||||||
{
|
{
|
||||||
PERFORM_TEST_ARGS *Args = (PERFORM_TEST_ARGS *)_arg;
|
PERFORM_TEST_ARGS *Args = (PERFORM_TEST_ARGS *)_arg;
|
||||||
TestOutputRoutine OutputRoutine = Args->OutputRoutine;
|
|
||||||
_PTEST Test = Args->Test;
|
_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(_GetCurrentThread(), THREAD_PRIORITY_IDLE);
|
||||||
_SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
|
|
||||||
|
|
||||||
memset(Buffer, 0, sizeof(Buffer));
|
memset(Args->Buffer, 0, sizeof(Args->Buffer));
|
||||||
|
|
||||||
_SEH_TRY {
|
_SEH_TRY {
|
||||||
_Result = TS_OK;
|
_Result = TS_OK;
|
||||||
_Buffer = Buffer;
|
_Buffer = Args->Buffer;
|
||||||
(Test->Routine)(TESTCMD_RUN);
|
(Test->Routine)(TESTCMD_RUN);
|
||||||
|
Args->Result = _Result;
|
||||||
} _SEH_HANDLE {
|
} _SEH_HANDLE {
|
||||||
_Result = TS_FAILED;
|
Args->Result = TS_FAILED;
|
||||||
sprintf(Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
|
sprintf(Args->Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
|
||||||
} _SEH_END;
|
} _SEH_END;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (_Result == TS_OK)
|
BOOL
|
||||||
{
|
IsContextChanged(LPCONTEXT context1, LPCONTEXT context2)
|
||||||
if (!_GetThreadTimes(hThread,
|
{
|
||||||
&time,
|
return memcmp(context1, context2, sizeof(CONTEXT)) != 0;
|
||||||
&time,
|
}
|
||||||
&time,
|
|
||||||
&ExecutionTime))
|
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)
|
||||||
{
|
{
|
||||||
ExecutionTime.dwLowDateTime = 0;
|
_TerminateThread(hThread, 0);
|
||||||
ExecutionTime.dwHighDateTime = 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,
|
sprintf(OutputBuffer,
|
||||||
"[%s] Success [%s]\n",
|
"[%s] Success [%s]\n",
|
||||||
TestName,
|
Args->TestName,
|
||||||
FormatExecutionTime(Format,
|
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
|
else
|
||||||
sprintf(OutputBuffer, "[%s] Failed (%s)\n", TestName, Buffer);
|
sprintf(OutputBuffer, "[%s] Failed (%s)\n", Args->TestName, Buffer);
|
||||||
|
|
||||||
if (OutputRoutine != NULL)
|
if (Args->OutputRoutine != NULL)
|
||||||
(*OutputRoutine)(OutputBuffer);
|
(*Args->OutputRoutine)(OutputBuffer);
|
||||||
else
|
else
|
||||||
DbgPrint(OutputBuffer);
|
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
|
VOID
|
||||||
|
@ -113,10 +206,12 @@ PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
char OutputBuffer[1024];
|
char OutputBuffer[1024];
|
||||||
char Name[200];
|
char Name[200];
|
||||||
|
DWORD TestType;
|
||||||
DWORD TimeOut;
|
DWORD TimeOut;
|
||||||
|
|
||||||
Args.OutputRoutine = OutputRoutine;
|
Args.OutputRoutine = OutputRoutine;
|
||||||
Args.TestName = Name;
|
Args.TestName = Name;
|
||||||
|
Args.Time = 0;
|
||||||
|
|
||||||
CurrentEntry = AllTests.Flink;
|
CurrentEntry = AllTests.Flink;
|
||||||
for (; CurrentEntry != &AllTests; CurrentEntry = NextEntry)
|
for (; CurrentEntry != &AllTests; CurrentEntry = NextEntry)
|
||||||
|
@ -141,40 +236,34 @@ PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
|
||||||
if ((TestName != NULL) && (_stricmp(Name, TestName) != 0))
|
if ((TestName != NULL) && (_stricmp(Name, TestName) != 0))
|
||||||
continue;
|
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 */
|
/* Get timeout for test */
|
||||||
TimeOut = 0;
|
TimeOut = 0;
|
||||||
_Result = TS_OK;
|
_Result = TS_OK;
|
||||||
_Buffer = (char *)&TimeOut;
|
_Buffer = (char *)&TimeOut;
|
||||||
(Current->Routine)(TESTCMD_TIMEOUT);
|
(Current->Routine)(TESTCMD_TIMEOUT);
|
||||||
if (_Result != TS_OK || TimeOut == INFINITE)
|
if (_Result != TS_OK || TimeOut == INFINITE)
|
||||||
TimeOut = 5000;
|
TimeOut = 5000;
|
||||||
|
|
||||||
/* Run test in thread */
|
/* Run test in a separate thread */
|
||||||
hThread = _CreateThread(NULL, 0, PerformTest, (PVOID)&Args, 0, NULL);
|
hThread = _CreateThread(NULL, 0, PerformTest, (PVOID)&Args, 0, NULL);
|
||||||
if (hThread == 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))
|
printf("[%s] Failed (CreateThread() failed: %ld)\n",
|
||||||
sprintf(OutputBuffer,
|
Name,
|
||||||
"[%s] Failed (timed out after %dms; TerminateThread() failed: %d)\n",
|
_GetLastError());
|
||||||
Name, (int)TimeOut, (unsigned int)_GetLastError());
|
Args.Result = TS_FAILED;
|
||||||
else
|
|
||||||
sprintf(OutputBuffer, "[%s] Failed (timed out after %dms)\n", Name, (int)TimeOut);
|
|
||||||
_CloseHandle(hThread);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
ControlTest(hThread, &Args, TestType, TimeOut);
|
||||||
_CloseHandle(hThread);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OutputRoutine != NULL)
|
DisplayResult(&Args, OutputBuffer);
|
||||||
(*OutputRoutine)(OutputBuffer);
|
|
||||||
else
|
|
||||||
DbgPrint(OutputBuffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,16 @@ void SetupOnce()
|
||||||
|
|
||||||
/* Valid values for Command parameter of TestRoutine */
|
/* Valid values for Command parameter of TestRoutine */
|
||||||
#define TESTCMD_RUN 0 /* Buffer contains information about what failed */
|
#define TESTCMD_RUN 0 /* Buffer contains information about what failed */
|
||||||
#define TESTCMD_TESTNAME 1 /* Buffer contains description of test */
|
#define TESTCMD_TESTTYPE 1 /* Buffer contains type of test */
|
||||||
#define TESTCMD_TIMEOUT 2 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
|
#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 */
|
/* Valid values for return values of TestRoutine */
|
||||||
|
#define TS_TIMEDOUT -2
|
||||||
#define TS_EXCEPTION -1
|
#define TS_EXCEPTION -1
|
||||||
#define TS_OK 0
|
#define TS_OK 0
|
||||||
#define TS_FAILED 1
|
#define TS_FAILED 1
|
||||||
|
@ -28,7 +34,7 @@ extern int _Result;
|
||||||
extern char *_Buffer;
|
extern char *_Buffer;
|
||||||
|
|
||||||
/* Macros to simplify tests */
|
/* Macros to simplify tests */
|
||||||
#define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
|
#define _DispatcherTypeTimeout(FunctionName, TestName, TestType, TimeOut) \
|
||||||
void \
|
void \
|
||||||
FunctionName(int Command) \
|
FunctionName(int Command) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -37,6 +43,9 @@ FunctionName(int Command) \
|
||||||
case TESTCMD_RUN: \
|
case TESTCMD_RUN: \
|
||||||
RunTest(); \
|
RunTest(); \
|
||||||
break; \
|
break; \
|
||||||
|
case TESTCMD_TESTTYPE: \
|
||||||
|
*(PDWORD)_Buffer = (DWORD)TestType; \
|
||||||
|
break; \
|
||||||
case TESTCMD_TESTNAME: \
|
case TESTCMD_TESTNAME: \
|
||||||
strcpy(_Buffer, TestName); \
|
strcpy(_Buffer, TestName); \
|
||||||
break; \
|
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
|
static inline void
|
||||||
AppendAssertion(char *message)
|
AppendAssertion(char *message)
|
||||||
|
@ -211,6 +227,18 @@ _GetCurrentProcess();
|
||||||
HANDLE STDCALL
|
HANDLE STDCALL
|
||||||
_GetCurrentThread();
|
_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
|
static inline PCHAR
|
||||||
FrameworkGetExportedFunctionNameInternal(_PAPI_DESCRIPTION ApiDescription)
|
FrameworkGetExportedFunctionNameInternal(_PAPI_DESCRIPTION ApiDescription)
|
||||||
|
|
|
@ -136,6 +136,8 @@
|
||||||
<symbol>ObReferenceObjectByName@32</symbol>
|
<symbol>ObReferenceObjectByName@32</symbol>
|
||||||
<symbol>HalQueryDisplayOwnership@0</symbol>
|
<symbol>HalQueryDisplayOwnership@0</symbol>
|
||||||
<symbol>IoDeviceObjectType</symbol>
|
<symbol>IoDeviceObjectType</symbol>
|
||||||
|
<symbol>@KfReleaseSpinLock@8</symbol>
|
||||||
|
<symbol>@KfAcquireSpinLock@4</symbol>
|
||||||
</component>
|
</component>
|
||||||
<component name="freetype.dll">
|
<component name="freetype.dll">
|
||||||
<symbol>FT_Init_FreeType</symbol>
|
<symbol>FT_Init_FreeType</symbol>
|
||||||
|
|
|
@ -31,7 +31,7 @@ static void RunTest()
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
SetupSurface(&surface, &rect);
|
SetupSurface(&surface, &rect);
|
||||||
for (i = 0; i < 1000; i++)
|
for (i = 0; i < 10000; i++)
|
||||||
{
|
{
|
||||||
BOOLEAN success = DIB_24BPP_ColorFill(&surface, &rect, color);
|
BOOLEAN success = DIB_24BPP_ColorFill(&surface, &rect, color);
|
||||||
_AssertTrue(success);
|
_AssertTrue(success);
|
||||||
|
@ -41,4 +41,4 @@ static void RunTest()
|
||||||
CleanupSurface(&surface);
|
CleanupSurface(&surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Dispatcher(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance")
|
_DispatcherType(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance", TT_PERFORMANCE)
|
||||||
|
|
|
@ -364,8 +364,9 @@ TestSupportCode::WriteStartupFile ( Module& module )
|
||||||
s = s + sprintf ( s, " LPSTR lpszCmdParam,\n" );
|
s = s + sprintf ( s, " LPSTR lpszCmdParam,\n" );
|
||||||
s = s + sprintf ( s, " int nCmdShow)\n" );
|
s = s + sprintf ( s, " int nCmdShow)\n" );
|
||||||
s = s + sprintf ( s, "{\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, " InitializeTests();\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, " RegisterTests();\n" );
|
||||||
s = s + sprintf ( s, " SetupOnce();\n" );
|
s = s + sprintf ( s, " SetupOnce();\n" );
|
||||||
s = s + sprintf ( s, " PerformTests(ConsoleWrite, NULL);\n" );
|
s = s + sprintf ( s, " PerformTests(ConsoleWrite, NULL);\n" );
|
||||||
|
|
Loading…
Reference in a new issue