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.

460 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. winperf.c
  5. Abstract:
  6. Test program for checking performance of Win32 API calls
  7. Author:
  8. Mark Lucovsky (markl) 26-Sep-1990
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include "basedll.h"
  16. //
  17. // Define local types.
  18. //
  19. #define EVENT_PAIR_ITERATIONS 20000
  20. #define NULL_API_ITERATIONS 10000
  21. #define DOMAIN_LOCK_ITERATIONS 40000
  22. #define CRITICAL_SECTION_LOCK_ITERATIONS 80000
  23. #define MUTEX_LOCK_ITERATIONS 20000
  24. typedef struct _PERFINFO {
  25. LARGE_INTEGER StartTime;
  26. LARGE_INTEGER StopTime;
  27. PCHAR Title;
  28. ULONG Iterations;
  29. } PERFINFO, *PPERFINFO;
  30. VOID
  31. StartBenchMark (
  32. IN PCHAR Title,
  33. IN ULONG Iterations,
  34. IN PPERFINFO PerfInfo
  35. );
  36. VOID
  37. FinishBenchMark (
  38. IN PPERFINFO PerfInfo
  39. );
  40. VOID
  41. GetTickCountTest(
  42. VOID
  43. );
  44. VOID
  45. EventPairTest (
  46. VOID
  47. );
  48. VOID
  49. QuickLpcTest (
  50. VOID
  51. );
  52. VOID
  53. SlowLpcTest (
  54. VOID
  55. );
  56. VOID
  57. DomainLockTest (
  58. VOID
  59. );
  60. VOID
  61. CriticalSectionLockTest (
  62. VOID
  63. );
  64. VOID
  65. MutexLockTest (
  66. VOID
  67. );
  68. DWORD
  69. main(
  70. int argc,
  71. char *argv[],
  72. char *envp[]
  73. )
  74. {
  75. (VOID)argc;
  76. (VOID)argv;
  77. (VOID)envp;
  78. GetTickCountTest();
  79. EventPairTest();
  80. QuickLpcTest();
  81. SlowLpcTest();
  82. DomainLockTest();
  83. CriticalSectionLockTest();
  84. MutexLockTest();
  85. ExitProcess(0);
  86. }
  87. HANDLE EventPair;
  88. VOID
  89. EventPairClient(
  90. LPVOID ThreadParameter
  91. )
  92. {
  93. NTSTATUS Status;
  94. //
  95. // Client does a NtSetLowWaitHighEventPair
  96. //
  97. do {
  98. Status = NtSetLowWaitHighEventPair(EventPair);
  99. }
  100. while (NT_SUCCESS(Status));
  101. ExitThread((DWORD)Status);
  102. }
  103. VOID
  104. EventPairTest (
  105. VOID
  106. )
  107. {
  108. ULONG Index;
  109. PERFINFO PerfInfo;
  110. HANDLE Thread;
  111. DWORD tid;
  112. ASSERT(NT_SUCCESS(NtCreateEventPair(&EventPair,EVENT_PAIR_ALL_ACCESS,NULL)));
  113. Thread = CreateThread(NULL,0L,EventPairClient,(LPVOID)99,0,&tid);
  114. Index = EVENT_PAIR_ITERATIONS;
  115. StartBenchMark("Event Pair Benchmark",
  116. EVENT_PAIR_ITERATIONS, &PerfInfo);
  117. NtWaitLowEventPair(EventPair);
  118. while (Index--) {
  119. NtSetHighWaitLowEventPair(EventPair);
  120. }
  121. FinishBenchMark(&PerfInfo);
  122. NtAlertThread(Thread);
  123. CloseHandle(Thread);
  124. CloseHandle(EventPair);
  125. return;
  126. }
  127. VOID
  128. GetTickCountTest (
  129. VOID
  130. )
  131. {
  132. ULONG Index;
  133. PERFINFO PerfInfo;
  134. HANDLE Thread;
  135. Index = EVENT_PAIR_ITERATIONS;
  136. StartBenchMark("Get Tick Count Benchmark",
  137. EVENT_PAIR_ITERATIONS, &PerfInfo);
  138. while (Index--) {
  139. GetTickCount();
  140. }
  141. FinishBenchMark(&PerfInfo);
  142. return;
  143. }
  144. VOID
  145. QuickLpcTest (
  146. VOID
  147. )
  148. {
  149. ULONG Index;
  150. PERFINFO PerfInfo;
  151. PCSR_NULLAPICALL_MSG Msg;
  152. QLPC_ACTION Action;
  153. CsrClientThreadConnect();
  154. Index = NULL_API_ITERATIONS;
  155. StartBenchMark("Quick Lpc Benchmark (no data)",
  156. NULL_API_ITERATIONS, &PerfInfo);
  157. while (Index--) {
  158. Msg = (PCSR_NULLAPICALL_MSG)
  159. CsrClientPushMessage( CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
  160. BasepNullApiCall
  161. ),
  162. sizeof( CSR_NULLAPICALL_MSG )
  163. );
  164. Msg->CountArguments = 0;
  165. ASSERT( CsrClientSendMessage( (PVOID) Msg, &Action ) == 0 );
  166. CsrClientPopMessage( (PVOID) Msg );
  167. }
  168. FinishBenchMark(&PerfInfo);
  169. Index = NULL_API_ITERATIONS;
  170. StartBenchMark("Quick Lpc Benchmark (40 bytes of data)",
  171. NULL_API_ITERATIONS, &PerfInfo);
  172. while (Index--) {
  173. Msg = (PCSR_NULLAPICALL_MSG)
  174. CsrClientPushMessage( CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
  175. BasepNullApiCall
  176. ),
  177. sizeof( CSR_NULLAPICALL_MSG )
  178. );
  179. Msg->CountArguments = -10;
  180. Msg->FastArguments[ 0 ] = 0;
  181. Msg->FastArguments[ 1 ] = 1;
  182. Msg->FastArguments[ 2 ] = 2;
  183. Msg->FastArguments[ 3 ] = 3;
  184. Msg->FastArguments[ 4 ] = 4;
  185. Msg->FastArguments[ 5 ] = 5;
  186. Msg->FastArguments[ 6 ] = 6;
  187. Msg->FastArguments[ 7 ] = 7;
  188. Msg->FastArguments[ 8 ] = 8;
  189. Msg->FastArguments[ 9 ] = 9;
  190. ASSERT( CsrClientSendMessage( (PVOID) Msg, &Action ) == 10 );
  191. CsrClientPopMessage( (PVOID) Msg );
  192. }
  193. FinishBenchMark(&PerfInfo);
  194. return;
  195. }
  196. ULONG
  197. BaseNullApiCall(
  198. IN LONG CountArguments,
  199. IN PCHAR *Arguments OPTIONAL
  200. );
  201. ULONG NullApiImmediateArguments[] = {
  202. 0,
  203. 1,
  204. 2,
  205. 3,
  206. 4,
  207. 5,
  208. 6,
  209. 7,
  210. 8,
  211. 9
  212. };
  213. PCHAR NullApiTextArguments[] = {
  214. "123456789012345678901234567890",
  215. "123456789012345678901234567890",
  216. "123456789012345678901234567890123456789012345678901234567890",
  217. NULL
  218. };
  219. VOID
  220. SlowLpcTest (
  221. VOID
  222. )
  223. {
  224. ULONG Index;
  225. PERFINFO PerfInfo;
  226. Index = NULL_API_ITERATIONS;
  227. StartBenchMark("Normal Lpc Benchmark (no data)",
  228. NULL_API_ITERATIONS, &PerfInfo);
  229. while (Index--) {
  230. BaseNullApiCall( 0, (PCHAR *)NULL );
  231. }
  232. FinishBenchMark(&PerfInfo);
  233. Index = NULL_API_ITERATIONS;
  234. StartBenchMark("Normal Lpc Benchmark (64 bytes of immediate data)",
  235. NULL_API_ITERATIONS, &PerfInfo);
  236. while (Index--) {
  237. BaseNullApiCall( -10, (PCHAR *)NullApiImmediateArguments );
  238. }
  239. FinishBenchMark(&PerfInfo);
  240. Index = NULL_API_ITERATIONS;
  241. StartBenchMark("Normal Lpc Benchmark (124 bytes of data)",
  242. NULL_API_ITERATIONS, &PerfInfo);
  243. while (Index--) {
  244. BaseNullApiCall( 3, NullApiTextArguments );
  245. }
  246. FinishBenchMark(&PerfInfo);
  247. return;
  248. }
  249. VOID
  250. DomainLockTest (
  251. VOID
  252. )
  253. {
  254. ULONG Index;
  255. PERFINFO PerfInfo;
  256. //
  257. // Announce start of benchmark and capture performance parmeters.
  258. //
  259. StartBenchMark("Domain Lock Benchmark",
  260. DOMAIN_LOCK_ITERATIONS, &PerfInfo);
  261. for (Index = 0; Index < DOMAIN_LOCK_ITERATIONS; Index += 1) {
  262. NtLockDisplayGroup(0);
  263. NtUnlockDisplayGroup(0);
  264. }
  265. //
  266. // Print out performance statistics.
  267. //
  268. FinishBenchMark(&PerfInfo);
  269. return;
  270. }
  271. VOID
  272. CriticalSectionLockTest (
  273. VOID
  274. )
  275. {
  276. ULONG Index;
  277. PERFINFO PerfInfo;
  278. CRITICAL_SECTION Crit;
  279. InitializeCriticalSection(&Crit);
  280. //
  281. // Announce start of benchmark and capture performance parmeters.
  282. //
  283. StartBenchMark("Critical Section Benchmark",
  284. CRITICAL_SECTION_LOCK_ITERATIONS, &PerfInfo);
  285. //
  286. // Repeatedly call a short system service.
  287. //
  288. for (Index = 0; Index < CRITICAL_SECTION_LOCK_ITERATIONS; Index += 1) {
  289. EnterCriticalSection(&Crit);
  290. LeaveCriticalSection(&Crit);
  291. }
  292. //
  293. // Print out performance statistics.
  294. //
  295. FinishBenchMark(&PerfInfo);
  296. return;
  297. }
  298. VOID
  299. MutexLockTest (
  300. VOID
  301. )
  302. {
  303. ULONG Index;
  304. PERFINFO PerfInfo;
  305. HANDLE Mutex;
  306. Mutex = CreateMutex(NULL,FALSE,NULL);
  307. //
  308. // Announce start of benchmark and capture performance parmeters.
  309. //
  310. StartBenchMark("Mutex Benchmark",
  311. MUTEX_LOCK_ITERATIONS, &PerfInfo);
  312. //
  313. // Repeatedly call a short system service.
  314. //
  315. for (Index = 0; Index < MUTEX_LOCK_ITERATIONS; Index += 1) {
  316. WaitForSingleObject(Mutex,-1);
  317. ReleaseMutex(Mutex);
  318. }
  319. //
  320. // Print out performance statistics.
  321. //
  322. FinishBenchMark(&PerfInfo);
  323. return;
  324. }
  325. VOID
  326. FinishBenchMark (
  327. IN PPERFINFO PerfInfo
  328. )
  329. {
  330. LARGE_INTEGER Duration;
  331. ULONG Length;
  332. ULONG Performance;
  333. //
  334. // Print results and announce end of test.
  335. //
  336. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StopTime);
  337. Duration = RtlLargeIntegerSubtract(PerfInfo->StopTime, PerfInfo->StartTime);
  338. Length = Duration.LowPart / 10000;
  339. DbgPrint(" Test time in milliseconds %d\n", Length);
  340. DbgPrint(" Number of iterations %d\n", PerfInfo->Iterations);
  341. Performance = PerfInfo->Iterations * 1000 / Length;
  342. DbgPrint(" Iterations per second %d\n", Performance);
  343. DbgPrint("*** End of Test ***\n\n");
  344. return;
  345. }
  346. VOID
  347. StartBenchMark (
  348. IN PCHAR Title,
  349. IN ULONG Iterations,
  350. IN PPERFINFO PerfInfo
  351. )
  352. {
  353. //
  354. // Announce start of test and the number of iterations.
  355. //
  356. DbgPrint("*** Start of test ***\n %s\n", Title);
  357. PerfInfo->Title = Title;
  358. PerfInfo->Iterations = Iterations;
  359. NtQuerySystemTime((PLARGE_INTEGER)&PerfInfo->StartTime);
  360. return;
  361. }