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.

224 lines
5.6 KiB

  1. #include "stdio.h"
  2. #include "string.h"
  3. #include "nt.h"
  4. #include "ntrtl.h"
  5. #include "nturtl.h"
  6. #include "windows.h"
  7. #define SPD_PROCESS_ITERATIONS 15
  8. //
  9. // Define local types.
  10. //
  11. typedef struct _PERFINFO {
  12. LARGE_INTEGER StartTime;
  13. LARGE_INTEGER StopTime;
  14. ULONG ContextSwitches;
  15. ULONG InterruptCount;
  16. ULONG FirstLevelFills;
  17. ULONG SecondLevelFills;
  18. ULONG SystemCalls;
  19. PCHAR Title;
  20. ULONG Iterations;
  21. } PERFINFO, *PPERFINFO;
  22. VOID
  23. SuspendedProcessTest(
  24. VOID
  25. );
  26. VOID
  27. FinishBenchMark (
  28. IN PPERFINFO PerfInfo
  29. );
  30. VOID
  31. StartBenchMark (
  32. IN PCHAR Title,
  33. IN ULONG Iterations,
  34. IN PPERFINFO PerfInfo
  35. );
  36. VOID
  37. main(
  38. int argc,
  39. char *argv[]
  40. )
  41. {
  42. if ( !_strcmpi("just exit",GetCommandLine()) ) {
  43. return;
  44. }
  45. SuspendedProcessTest();
  46. return;
  47. }
  48. VOID
  49. SuspendedProcessTest (
  50. VOID
  51. )
  52. {
  53. PERFINFO PerfInfo;
  54. STARTUPINFO si;
  55. PROCESS_INFORMATION pi[SPD_PROCESS_ITERATIONS];
  56. BOOL b;
  57. int Index;
  58. CHAR Buffer[256];
  59. KPRIORITY Base;
  60. GetModuleFileName(0,Buffer,256);
  61. RtlZeroMemory(&si,sizeof(si));
  62. si.cb = sizeof(si);
  63. Base = 13;
  64. NtSetInformationProcess(
  65. NtCurrentProcess(),
  66. ProcessBasePriority,
  67. (PVOID) &Base,
  68. sizeof(Base)
  69. );
  70. // SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
  71. StartBenchMark("Suspended Process Creation Benchmark)",
  72. SPD_PROCESS_ITERATIONS,
  73. &PerfInfo);
  74. for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
  75. b = CreateProcess(
  76. Buffer,
  77. "just exit",
  78. NULL,
  79. NULL,
  80. TRUE,
  81. CREATE_SUSPENDED,
  82. NULL,
  83. NULL,
  84. &si,
  85. &pi[Index]
  86. );
  87. if ( !b ) {
  88. printf("failed %ld\n",Index);
  89. }
  90. }
  91. //
  92. // Print out performance statistics.
  93. //
  94. FinishBenchMark(&PerfInfo);
  95. // SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
  96. StartBenchMark("Process Startup/Exit Benchmark)",
  97. SPD_PROCESS_ITERATIONS,
  98. &PerfInfo);
  99. for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
  100. ResumeThread(pi[Index].hThread);
  101. CloseHandle(pi[Index].hThread);
  102. WaitForSingleObject(pi[Index].hProcess,-1);
  103. CloseHandle(pi[Index].hProcess);
  104. }
  105. FinishBenchMark(&PerfInfo);
  106. //
  107. // End of event1 context switch test.
  108. //
  109. return;
  110. }
  111. VOID
  112. FinishBenchMark (
  113. IN PPERFINFO PerfInfo
  114. )
  115. {
  116. ULONG ContextSwitches;
  117. LARGE_INTEGER Duration;
  118. ULONG FirstLevelFills;
  119. ULONG InterruptCount;
  120. ULONG Length;
  121. ULONG Performance;
  122. ULONG SecondLevelFills;
  123. NTSTATUS Status;
  124. ULONG SystemCalls;
  125. SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
  126. //
  127. // Print results and announce end of test.
  128. //
  129. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
  130. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  131. (PVOID)&SystemInfo,
  132. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  133. NULL);
  134. if (NT_SUCCESS(Status) == FALSE) {
  135. printf("Failed to query performance information, status = %lx\n", Status);
  136. return;
  137. }
  138. Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
  139. Length = Duration.LowPart / 10000;
  140. printf(" Test time in milliseconds %d\n", Length);
  141. printf(" Number of iterations %d\n", PerfInfo->Iterations);
  142. Performance = PerfInfo->Iterations * 1000 / Length;
  143. printf(" Iterations per second %d\n", Performance);
  144. ContextSwitches = SystemInfo.ContextSwitches - PerfInfo->ContextSwitches;
  145. FirstLevelFills = SystemInfo.FirstLevelTbFills - PerfInfo->FirstLevelFills;
  146. InterruptCount = SystemInfo.InterruptCount - PerfInfo->InterruptCount;
  147. SecondLevelFills = SystemInfo.SecondLevelTbFills - PerfInfo->SecondLevelFills;
  148. SystemCalls = SystemInfo.SystemCalls - PerfInfo->SystemCalls;
  149. printf(" First Level TB Fills %d\n", FirstLevelFills);
  150. printf(" Second Level TB Fills %d\n", SecondLevelFills);
  151. printf(" Number of Interrupts %d\n", InterruptCount);
  152. printf(" Total Context Switches %d\n", ContextSwitches);
  153. printf(" Number of System Calls %d\n", SystemCalls);
  154. printf("*** End of Test ***\n\n");
  155. return;
  156. }
  157. VOID
  158. StartBenchMark (
  159. IN PCHAR Title,
  160. IN ULONG Iterations,
  161. IN PPERFINFO PerfInfo
  162. )
  163. {
  164. NTSTATUS Status;
  165. SYSTEM_PERFORMANCE_INFORMATION SystemInfo;
  166. //
  167. // Announce start of test and the number of iterations.
  168. //
  169. printf("*** Start of test ***\n %s\n", Title);
  170. PerfInfo->Title = Title;
  171. PerfInfo->Iterations = Iterations;
  172. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
  173. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  174. (PVOID)&SystemInfo,
  175. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  176. NULL);
  177. if (NT_SUCCESS(Status) == FALSE) {
  178. printf("Failed to query performance information, status = %lx\n", Status);
  179. return;
  180. }
  181. PerfInfo->ContextSwitches = SystemInfo.ContextSwitches;
  182. PerfInfo->FirstLevelFills = SystemInfo.FirstLevelTbFills;
  183. PerfInfo->InterruptCount = SystemInfo.InterruptCount;
  184. PerfInfo->SecondLevelFills = SystemInfo.SecondLevelTbFills;
  185. PerfInfo->SystemCalls = SystemInfo.SystemCalls;
  186. return;
  187. }