Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.4 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <assert.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <windows.h>
  8. #include <string.h>
  9. #include <memory.h>
  10. #include <process.h>
  11. #define WAIT_MULTIPLE_ITERATIONS 10000
  12. HANDLE WaitHandles[64];
  13. //
  14. // Define local types.
  15. //
  16. typedef struct _PERFINFO {
  17. LARGE_INTEGER StartTime;
  18. LARGE_INTEGER StopTime;
  19. ULONG ContextSwitches;
  20. ULONG FirstLevelFills;
  21. ULONG SecondLevelFills;
  22. ULONG SystemCalls;
  23. PCHAR Title;
  24. ULONG Iterations;
  25. } PERFINFO, *PPERFINFO;
  26. VOID
  27. FinishBenchMark (
  28. IN PPERFINFO PerfInfo
  29. )
  30. {
  31. ULONG ContextSwitches;
  32. LARGE_INTEGER Duration;
  33. ULONG FirstLevelFills;
  34. ULONG Length;
  35. ULONG Performance;
  36. ULONG SecondLevelFills;
  37. NTSTATUS Status;
  38. ULONG SystemCalls;
  39. SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
  40. //
  41. // Print results and announce end of test.
  42. //
  43. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
  44. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  45. (PVOID)&SystemInfo,
  46. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  47. NULL);
  48. if (NT_SUCCESS(Status) == FALSE) {
  49. printf("Failed to query performance information, status = %lx\n", Status);
  50. return;
  51. }
  52. Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
  53. Length = Duration.LowPart / 10000;
  54. printf(" Test time in milliseconds %d\n", Length);
  55. printf(" Number of iterations %d\n", PerfInfo->Iterations);
  56. Performance = PerfInfo->Iterations * 1000 / Length;
  57. printf(" Iterations per second %d\n", Performance);
  58. ContextSwitches = SystemInfo.ContextSwitches - PerfInfo->ContextSwitches;
  59. FirstLevelFills = SystemInfo.FirstLevelTbFills - PerfInfo->FirstLevelFills;
  60. SecondLevelFills = SystemInfo.SecondLevelTbFills - PerfInfo->SecondLevelFills;
  61. SystemCalls = SystemInfo.SystemCalls - PerfInfo->SystemCalls;
  62. printf(" First Level TB Fills %d\n", FirstLevelFills);
  63. printf(" Second Level TB Fills %d\n", SecondLevelFills);
  64. printf(" Total Context Switches %d\n", ContextSwitches);
  65. printf(" Number of System Calls %d\n", SystemCalls);
  66. printf("*** End of Test ***\n\n");
  67. return;
  68. }
  69. VOID
  70. StartBenchMark (
  71. IN PCHAR Title,
  72. IN ULONG Iterations,
  73. IN PPERFINFO PerfInfo
  74. )
  75. {
  76. NTSTATUS Status;
  77. SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
  78. //
  79. // Announce start of test and the number of iterations.
  80. //
  81. printf("*** Start of test ***\n %s\n", Title);
  82. PerfInfo->Title = Title;
  83. PerfInfo->Iterations = Iterations;
  84. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
  85. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  86. (PVOID)&SystemInfo,
  87. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  88. NULL);
  89. if (NT_SUCCESS(Status) == FALSE) {
  90. printf("Failed to query performance information, status = %lx\n", Status);
  91. return;
  92. }
  93. PerfInfo->ContextSwitches = SystemInfo.ContextSwitches;
  94. PerfInfo->FirstLevelFills = SystemInfo.FirstLevelTbFills;
  95. PerfInfo->SecondLevelFills = SystemInfo.SecondLevelTbFills;
  96. PerfInfo->SystemCalls = SystemInfo.SystemCalls;
  97. return;
  98. }
  99. VOID
  100. WaitMultipleTest()
  101. {
  102. PERFINFO PerfInfo;
  103. int i;
  104. StartBenchMark(
  105. "Wait Single Object",
  106. WAIT_MULTIPLE_ITERATIONS,
  107. &PerfInfo
  108. );
  109. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  110. WaitForSingleObject(WaitHandles[0],INFINITE); // Wait Single Object
  111. }
  112. FinishBenchMark(&PerfInfo);
  113. StartBenchMark(
  114. "Wait Multiple Test 1 Object",
  115. WAIT_MULTIPLE_ITERATIONS,
  116. &PerfInfo
  117. );
  118. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  119. WaitForMultipleObjects(1,WaitHandles,FALSE,INFINITE); // Wait Any, 1 Object
  120. }
  121. FinishBenchMark(&PerfInfo);
  122. StartBenchMark(
  123. "Wait Multiple Test 8 Objects",
  124. WAIT_MULTIPLE_ITERATIONS,
  125. &PerfInfo
  126. );
  127. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  128. WaitForMultipleObjects(8,WaitHandles,FALSE,INFINITE); // Wait Any, 8 Objects
  129. }
  130. FinishBenchMark(&PerfInfo);
  131. StartBenchMark(
  132. "Wait Multiple Test 16 Objects",
  133. WAIT_MULTIPLE_ITERATIONS,
  134. &PerfInfo
  135. );
  136. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  137. WaitForMultipleObjects(16,WaitHandles,FALSE,INFINITE); // Wait Any, 16 Objects
  138. }
  139. FinishBenchMark(&PerfInfo);
  140. StartBenchMark(
  141. "Wait Multiple Test 32 Objects",
  142. WAIT_MULTIPLE_ITERATIONS,
  143. &PerfInfo
  144. );
  145. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  146. WaitForMultipleObjects(32,WaitHandles,FALSE,INFINITE); // Wait Any, 32 Objects
  147. }
  148. FinishBenchMark(&PerfInfo);
  149. StartBenchMark(
  150. "Wait Multiple Test 64 Objects",
  151. WAIT_MULTIPLE_ITERATIONS,
  152. &PerfInfo
  153. );
  154. for ( i=0;i<WAIT_MULTIPLE_ITERATIONS;i++) {
  155. WaitForMultipleObjects(64,WaitHandles,FALSE,INFINITE); // Wait Any, 64 Objects
  156. }
  157. FinishBenchMark(&PerfInfo);
  158. }
  159. DWORD
  160. _cdecl
  161. main(
  162. int argc,
  163. char *argv[],
  164. char *envp[]
  165. )
  166. {
  167. int i;
  168. for(i=0;i<64;i++){
  169. WaitHandles[i] = CreateEvent(NULL,TRUE,TRUE,NULL);
  170. }
  171. WaitMultipleTest();
  172. return 0;
  173. }