Count only scheduled time when running performance tests
Modified: trunk/reactos/regtests/regtests/regtests.c
Modified: trunk/reactos/regtests/regtests/regtests.def
Modified: trunk/reactos/regtests/shared/regtests.c
Modified: trunk/reactos/regtests/shared/regtests.h
Modified: trunk/reactos/subsys/win32k/tests/stubs.xml
Modified: trunk/reactos/subsys/win32k/tests/tests/DIB_24BPP_ColorFill-performance.c
Modified: trunk/reactos/tools/rbuild/testsupportcode.cpp

Modified: trunk/reactos/regtests/regtests/regtests.c
--- trunk/reactos/regtests/regtests/regtests.c	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/regtests/regtests.c	2005-06-19 12:41:22 UTC (rev 16091)
@@ -98,3 +98,27 @@
 {
   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);
+}

Modified: trunk/reactos/regtests/regtests/regtests.def
--- trunk/reactos/regtests/regtests/regtests.def	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/regtests/regtests.def	2005-06-19 12:41:22 UTC (rev 16091)
@@ -14,3 +14,7 @@
 _SetThreadPriority@8
 _GetCurrentProcess@0
 _GetCurrentThread@0
+_GetThreadContext@8
+_SuspendThread@4
+_ResumeThread@4
+_Sleep@4

Modified: trunk/reactos/regtests/shared/regtests.c
--- trunk/reactos/regtests/shared/regtests.c	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/shared/regtests.c	2005-06-19 12:41:22 UTC (rev 16091)
@@ -24,6 +24,9 @@
   TestOutputRoutine OutputRoutine;
   _PTEST Test;
   LPSTR TestName;
+  DWORD Result;
+  char Buffer[5000];
+  DWORD Time;
 } PERFORM_TEST_ARGS;
 
 int _Result;
@@ -38,13 +41,11 @@
 }
 
 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,58 +53,150 @@
 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;
+  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,
-                                  &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;
+    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
 PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
 {
   PLIST_ENTRY CurrentEntry;
@@ -113,11 +206,13 @@
   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 @@
       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);
     }
 }
 

Modified: trunk/reactos/regtests/shared/regtests.h
--- trunk/reactos/regtests/shared/regtests.h	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/shared/regtests.h	2005-06-19 12:41:22 UTC (rev 16091)
@@ -16,10 +16,16 @@
 
 /* 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 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 @@
       case TESTCMD_RUN: \
         RunTest(); \
         break; \
+      case TESTCMD_TESTTYPE: \
+        *(PDWORD)_Buffer = (DWORD)TestType; \
+        break; \
       case TESTCMD_TESTNAME: \
         strcpy(_Buffer, TestName); \
         break; \
@@ -49,8 +58,15 @@
     } \
 }
 
-#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,7 +227,19 @@
 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)
 {

Modified: trunk/reactos/subsys/win32k/tests/stubs.xml
--- trunk/reactos/subsys/win32k/tests/stubs.xml	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/subsys/win32k/tests/stubs.xml	2005-06-19 12:41:22 UTC (rev 16091)
@@ -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>

Modified: trunk/reactos/subsys/win32k/tests/tests/DIB_24BPP_ColorFill-performance.c
--- trunk/reactos/subsys/win32k/tests/tests/DIB_24BPP_ColorFill-performance.c	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/subsys/win32k/tests/tests/DIB_24BPP_ColorFill-performance.c	2005-06-19 12:41:22 UTC (rev 16091)
@@ -31,7 +31,7 @@
   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 @@
   CleanupSurface(&surface);
 }
 
-_Dispatcher(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance")
+_DispatcherType(Dib_24bpp_colorfill_performanceTest, "DIB_24BPP_ColorFill performance", TT_PERFORMANCE)

Modified: trunk/reactos/tools/rbuild/testsupportcode.cpp
--- trunk/reactos/tools/rbuild/testsupportcode.cpp	2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/tools/rbuild/testsupportcode.cpp	2005-06-19 12:41:22 UTC (rev 16091)
@@ -364,8 +364,9 @@
 	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" );