Count only scheduled time when running performance tests
authorCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 19 Jun 2005 12:41:22 +0000 (12:41 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 19 Jun 2005 12:41:22 +0000 (12:41 +0000)
svn path=/trunk/; revision=16091

reactos/regtests/regtests/regtests.c
reactos/regtests/regtests/regtests.def
reactos/regtests/shared/regtests.c
reactos/regtests/shared/regtests.h
reactos/subsys/win32k/tests/stubs.xml
reactos/subsys/win32k/tests/tests/DIB_24BPP_ColorFill-performance.c
reactos/tools/rbuild/testsupportcode.cpp

index b904be1..e321aae 100755 (executable)
@@ -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);
+}
index 166d550..3cd1eec 100644 (file)
@@ -14,3 +14,7 @@ _SetPriorityClass@8
 _SetThreadPriority@8
 _GetCurrentProcess@0
 _GetCurrentThread@0
+_GetThreadContext@8
+_SuspendThread@4
+_ResumeThread@4
+_Sleep@4
index 9c142a6..adc14c7 100755 (executable)
@@ -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,13 +41,11 @@ InitializeTests()
 }
 
 char*
-FormatExecutionTime(char *buffer, LPFILETIME time)
+FormatExecutionTime(char *buffer, ULONG milliseconds)
 {
-  ULONG milliseconds = time->dwLowDateTime / 10000;
-  
   sprintf(buffer,
-             "%ldms",
-             milliseconds);
+         "%ldms",
+         milliseconds);
   return buffer;
 }
 
@@ -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(Args->Buffer, 0, sizeof(Args->Buffer));
 
-  memset(Buffer, 0, sizeof(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;
+  return 1;
+}
 
-  if (_Result == TS_OK)
-    {
-      if (!_GetThreadTimes(hThread,
-                              &time,
-                              &time,
-                              &time,
-                              &ExecutionTime))
+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)
       {
-        ExecutionTime.dwLowDateTime = 0;
-        ExecutionTime.dwHighDateTime = 0;
+        _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,
+                                  Args->Time));
+    }
+  else if (Args->Result == TS_TIMEDOUT)
+    {
+      sprintf(OutputBuffer,
+              "[%s] Timed out [%s]\n",
+              Args->TestName,
               FormatExecutionTime(Format,
-                                  &ExecutionTime));
+                                  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;
+    DbgPrint(OutputBuffer);
+}
+
+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,11 +206,13 @@ 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,40 +236,34 @@ 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;
       _Buffer = (char *)&TimeOut;
       (Current->Routine)(TESTCMD_TIMEOUT);
       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);
       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);
     }
 }
 
index 93ce5fe..65df8c2 100755 (executable)
@@ -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)
index 06dd4a9..b5abcec 100644 (file)
        <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>
index 3d1b823..60e4cb8 100644 (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)
index f35b9af..e238e0e 100644 (file)
@@ -364,8 +364,9 @@ 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, "  InitializeTests();\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" );
        s = s + sprintf ( s, "  PerformTests(ConsoleWrite, NULL);\n" );