Leaked source code of windows server 2003
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.

553 lines
11 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <string.h>
  5. #define FIBER_COUNT 50000000
  6. #define FIVEK 5000
  7. #define TENK 10000
  8. #define ONEHUNK 100000
  9. #define ONEMIL 1000000
  10. #define MEMORY_TEST 200000000
  11. VOID
  12. _fastcall
  13. MemToReg (
  14. IN ULONG Count,
  15. IN PULONG Address
  16. );
  17. VOID
  18. _fastcall
  19. RegToMem (
  20. IN ULONG Count,
  21. IN PULONG Address
  22. );
  23. typedef struct _FLS_VALUE {
  24. DWORD Value1;
  25. DWORD Value2;
  26. } FLS_VALUE, *PFLS_VALUE;
  27. //
  28. // Define local types.
  29. //
  30. typedef struct _PERFINFO {
  31. DWORD StartTime;
  32. DWORD StopTime;
  33. LPSTR Title;
  34. DWORD Iterations;
  35. } PERFINFO, *PPERFINFO;
  36. VOID
  37. FinishBenchMark (
  38. IN PPERFINFO PerfInfo
  39. )
  40. {
  41. DWORD ContextSwitches;
  42. DWORD Duration;
  43. DWORD Performance;
  44. //
  45. // Print results and announce end of test.
  46. //
  47. PerfInfo->StopTime = GetTickCount();
  48. Duration = PerfInfo->StopTime - PerfInfo->StartTime;
  49. printf(" Test time in milliseconds %d\n", Duration);
  50. printf(" Number of iterations %d\n", PerfInfo->Iterations);
  51. Performance = (DWORD)((ULONG64)PerfInfo->Iterations * 1000 / Duration);
  52. printf(" Iterations per second %d\n", Performance);
  53. printf("*** End of Test ***\n\n");
  54. return;
  55. }
  56. VOID
  57. StartBenchMark (
  58. IN PCHAR Title,
  59. IN DWORD Iterations,
  60. IN PPERFINFO PerfInfo
  61. )
  62. {
  63. //
  64. // Announce start of test and the number of iterations.
  65. //
  66. printf("*** Start of test ***\n %s\n", Title);
  67. PerfInfo->Title = Title;
  68. PerfInfo->Iterations = Iterations;
  69. PerfInfo->StartTime = GetTickCount();
  70. return;
  71. }
  72. VOID
  73. VqTest(
  74. VOID
  75. )
  76. {
  77. PERFINFO PerfInfo;
  78. int i;
  79. PVOID Pv;
  80. DWORD dw;
  81. MEMORY_BASIC_INFORMATION BasicInfo;
  82. //
  83. // Reserve 64k and commit one page
  84. //
  85. Pv = VirtualAlloc(NULL,65536,MEM_RESERVE,PAGE_READWRITE);
  86. if ( !Pv ) {
  87. printf("Virtual Alloc(a) Failed %d\n",GetLastError());
  88. ExitProcess(1);
  89. }
  90. Pv = VirtualAlloc(Pv,4096,MEM_COMMIT,PAGE_READWRITE);
  91. if ( !Pv ) {
  92. printf("Virtual Alloc(b) Failed %d\n",GetLastError());
  93. ExitProcess(1);
  94. }
  95. SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
  96. StartBenchMark(
  97. "Virtual Query Test",
  98. 5*ONEHUNK,
  99. &PerfInfo
  100. );
  101. for ( i=0;i<5*ONEHUNK;i++) {
  102. dw = VirtualQuery(Pv,&BasicInfo,sizeof(BasicInfo));
  103. }
  104. FinishBenchMark(&PerfInfo);
  105. SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
  106. }
  107. VOID
  108. MulDivTest(
  109. VOID
  110. )
  111. {
  112. PERFINFO PerfInfo;
  113. int i;
  114. SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
  115. StartBenchMark(
  116. "MulDiv(4,2,5) Test",
  117. 5*ONEMIL,
  118. &PerfInfo
  119. );
  120. for ( i=0;i<5*ONEMIL;i++) {
  121. MulDiv(4,2,5);
  122. }
  123. FinishBenchMark(&PerfInfo);
  124. StartBenchMark(
  125. "MulDiv(-4,2,5) Test",
  126. 5*ONEMIL,
  127. &PerfInfo
  128. );
  129. for ( i=0;i<5*ONEMIL;i++) {
  130. MulDiv(-4,2,5);
  131. }
  132. FinishBenchMark(&PerfInfo);
  133. StartBenchMark(
  134. "MulDiv(4,-2,5) Test",
  135. 5*ONEMIL,
  136. &PerfInfo
  137. );
  138. for ( i=0;i<5*ONEMIL;i++) {
  139. MulDiv(4,-2,5);
  140. }
  141. FinishBenchMark(&PerfInfo);
  142. StartBenchMark(
  143. "MulDiv(-4,-2,5) Test",
  144. 5*ONEMIL,
  145. &PerfInfo
  146. );
  147. for ( i=0;i<5*ONEMIL;i++) {
  148. MulDiv(-4,-2,5);
  149. }
  150. FinishBenchMark(&PerfInfo);
  151. StartBenchMark(
  152. "MulDiv(0x10,0x400,0) Test",
  153. 5*ONEMIL,
  154. &PerfInfo
  155. );
  156. for ( i=0;i<5*ONEMIL;i++) {
  157. MulDiv(0x10,0x400,0);
  158. }
  159. FinishBenchMark(&PerfInfo);
  160. StartBenchMark(
  161. "MulDiv(0x10,0x40000000,2) Test",
  162. 5*ONEMIL,
  163. &PerfInfo
  164. );
  165. for ( i=0;i<5*ONEMIL;i++) {
  166. MulDiv(0x10,0x40000000,2);
  167. }
  168. FinishBenchMark(&PerfInfo);
  169. SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
  170. }
  171. VOID
  172. GfaTest(
  173. LPSTR Str
  174. )
  175. {
  176. PERFINFO PerfInfo;
  177. int i;
  178. StartBenchMark(
  179. "GetFileAttributes Test",
  180. FIVEK,
  181. &PerfInfo
  182. );
  183. for ( i=0;i<FIVEK;i++) {
  184. GetFileAttributes(Str);
  185. }
  186. FinishBenchMark(&PerfInfo);
  187. }
  188. VOID
  189. GmhTest(
  190. VOID
  191. )
  192. {
  193. PERFINFO PerfInfo;
  194. int i;
  195. StartBenchMark(
  196. "GetModuleHandle Test",
  197. ONEHUNK,
  198. &PerfInfo
  199. );
  200. for ( i=0;i<ONEHUNK;i++) {
  201. GetModuleHandle("kernel32.dll");
  202. }
  203. FinishBenchMark(&PerfInfo);
  204. }
  205. LPVOID Fibers[2];
  206. FLS_VALUE FlsValue1;
  207. FLS_VALUE FlsValue2;
  208. VOID
  209. SwitchToFiber0 (
  210. VOID
  211. )
  212. {
  213. SwitchToFiber(Fibers[0]);
  214. return;
  215. }
  216. VOID
  217. FiberRoutine1(
  218. LPVOID lpParameter
  219. )
  220. {
  221. PCHAR Name;
  222. PFLS_VALUE Value;
  223. Value = GetFiberData();
  224. if (FlsSetValue(Value->Value1, (PVOID)Value->Value1) == FALSE) {
  225. printf("fiber 1 - set index %d failed\n", Value->Value1);
  226. }
  227. if (FlsSetValue(Value->Value2, (PVOID)Value->Value2) == FALSE) {
  228. printf("fiber 1 - set index %d failed\n", Value->Value2);
  229. }
  230. Name = strtok("fiber 1", ":");
  231. printf("%s starting loop\n", Name);
  232. for(;;) {
  233. if (FlsGetValue(Value->Value1) != (PVOID)Value->Value1) {
  234. printf("fiber 1 - get value at index % d return wrong value %d\n",
  235. Value->Value1,
  236. FlsGetValue(Value->Value1));
  237. }
  238. if (FlsGetValue(Value->Value2) != (PVOID)Value->Value2) {
  239. printf("fiber 1 - get value at index % d return wrong value %d\n",
  240. Value->Value2,
  241. FlsGetValue(Value->Value2));
  242. }
  243. SwitchToFiber0();
  244. }
  245. }
  246. VOID
  247. SwitchToFiber1 (
  248. VOID
  249. )
  250. {
  251. SwitchToFiber(Fibers[1]);
  252. return;
  253. }
  254. VOID
  255. FiberRoutine0(
  256. LPVOID lpParameter
  257. )
  258. {
  259. PFLS_VALUE Value;
  260. PERFINFO PerfInfo;
  261. int i;
  262. PCHAR Name;
  263. StartBenchMark(
  264. "Fiber Switch Test",
  265. FIBER_COUNT,
  266. &PerfInfo
  267. );
  268. Value = GetFiberData();
  269. if (FlsSetValue(Value->Value1, (PVOID)Value->Value1) == FALSE) {
  270. printf("fiber 0 - set index %d failed\n", Value->Value1);
  271. }
  272. if (FlsSetValue(Value->Value2, (PVOID)Value->Value2) == FALSE) {
  273. printf("fiber 0 - set index %d failed\n", Value->Value2);
  274. }
  275. Name = strtok("Fiber 0", ":");
  276. printf("%s starting loop\n", Name);
  277. for ( i = 0; i < FIBER_COUNT; i++) {
  278. if (FlsGetValue(Value->Value1) != (PVOID)Value->Value1) {
  279. printf("fiber 0 - get value at index % d return wrong value %d\n",
  280. Value->Value1,
  281. FlsGetValue(Value->Value1));
  282. }
  283. if (FlsGetValue(Value->Value2) != (PVOID)Value->Value2) {
  284. printf("fiber 0 - get value at index % d return wrong value %d\n",
  285. Value->Value2,
  286. FlsGetValue(Value->Value2));
  287. }
  288. SwitchToFiber1();
  289. }
  290. FinishBenchMark(&PerfInfo);
  291. }
  292. VOID
  293. WINAPI
  294. FibCallback (
  295. PVOID Data
  296. )
  297. {
  298. if (((DWORD)Data != 0) &&
  299. ((DWORD)Data != FlsValue1.Value1) &&
  300. ((DWORD)Data != FlsValue1.Value2) &&
  301. ((DWORD)Data != FlsValue2.Value1) &&
  302. ((DWORD)Data != FlsValue2.Value2)) {
  303. printf("callback routine incorrectly called for data %d\n", (DWORD)Data);
  304. }
  305. return;
  306. }
  307. VOID
  308. FibTst(
  309. DWORD Flags
  310. )
  311. {
  312. Fibers[0] = ConvertThreadToFiberEx((LPVOID)&FlsValue1, Flags);
  313. Fibers[1] = CreateFiberEx(0, 0, Flags, FiberRoutine1, (LPVOID)&FlsValue2);
  314. FlsValue1.Value1 = FlsAlloc(&FibCallback);
  315. FlsValue1.Value2 = FlsAlloc(&FibCallback);
  316. FlsValue2.Value1 = FlsAlloc(&FibCallback);
  317. FlsValue2.Value2 = FlsAlloc(&FibCallback);
  318. FiberRoutine0((LPVOID)1);
  319. if (ConvertFiberToThread() == FALSE) {
  320. printf("fiber convertion to thread failed\n");
  321. }
  322. DeleteFiber(Fibers[1]);
  323. if (FlsFree(FlsValue1.Value1) == FALSE) {
  324. printf("thread 0 unable to free index %d\n", FlsValue1.Value1);
  325. }
  326. if (FlsFree(FlsValue1.Value2) == FALSE) {
  327. printf("thread 0 unable to free index %d\n", FlsValue1.Value2);
  328. }
  329. if (FlsFree(FlsValue2.Value1) == FALSE) {
  330. printf("thread 0 unable to free index %d\n", FlsValue2.Value1);
  331. }
  332. if (FlsFree(FlsValue2.Value2) == FALSE) {
  333. printf("thread 0 unable to free index %d\n", FlsValue2.Value2);
  334. }
  335. return;
  336. }
  337. VOID
  338. MemoryTest (
  339. VOID
  340. )
  341. {
  342. PULONG Address;
  343. CHAR Buffer[512];
  344. ULONG Count;
  345. PERFINFO PerfInfo;
  346. //
  347. // Memory to register - aligned.
  348. //
  349. Address = (PULONG)(((ULONG)(&Buffer[128]) + 3) & ~3);
  350. StartBenchMark("Memory To Register Aligned Test",
  351. MEMORY_TEST,
  352. &PerfInfo);
  353. MemToReg(MEMORY_TEST, Address);
  354. FinishBenchMark(&PerfInfo);
  355. //
  356. // Memory to register - unaligned within cache line
  357. //
  358. Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) + 1);
  359. StartBenchMark("Memory To Register Unaligned Within Cache Line Test",
  360. MEMORY_TEST,
  361. &PerfInfo);
  362. MemToReg(MEMORY_TEST, Address);
  363. FinishBenchMark(&PerfInfo);
  364. //
  365. // Memory to register - unaligned across cache line
  366. //
  367. Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) - 1);
  368. StartBenchMark("Memory To Register Unaligned Across Cache Line Test",
  369. MEMORY_TEST / 2,
  370. &PerfInfo);
  371. MemToReg(MEMORY_TEST, Address);
  372. FinishBenchMark(&PerfInfo);
  373. //
  374. // Register to memory - aligned.
  375. //
  376. Address = (PULONG)(((ULONG)(&Buffer[256]) + 3) & ~3);
  377. StartBenchMark("Register To Memory Aligned Test",
  378. MEMORY_TEST,
  379. &PerfInfo);
  380. RegToMem(MEMORY_TEST, Address);
  381. FinishBenchMark(&PerfInfo);
  382. //
  383. // Register to Memory - unaligned within cache line
  384. //
  385. Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) + 1);
  386. StartBenchMark("Register To Memory Unaligned Within Cache Line Test",
  387. MEMORY_TEST,
  388. &PerfInfo);
  389. RegToMem(MEMORY_TEST, Address);
  390. FinishBenchMark(&PerfInfo);
  391. //
  392. // Register to Memory - unaligned across cache line
  393. //
  394. Address = (PULONG)((((ULONG)(&Buffer[256]) + 127) & ~127) - 1);
  395. StartBenchMark("Register To Memory Unaligned Across Cache Line Test",
  396. MEMORY_TEST / 2,
  397. &PerfInfo);
  398. RegToMem(MEMORY_TEST, Address);
  399. FinishBenchMark(&PerfInfo);
  400. return;
  401. }
  402. DWORD
  403. _cdecl
  404. main(
  405. int argc,
  406. char *argv[],
  407. char *envp[]
  408. )
  409. {
  410. // VqTest();
  411. // MulDivTest();
  412. // GmhTest();
  413. // if ( argc > 1 ) {
  414. // GfaTest(argv[1]);
  415. // }
  416. FibTst(0);
  417. FibTst(FIBER_FLAG_FLOAT_SWITCH);
  418. // MemoryTest();
  419. ExitThread(0);
  420. return 0;
  421. }