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.

670 lines
21 KiB

  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <memory.h>
  5. #include <nt.h>
  6. #include <ntrtl.h>
  7. #include <nturtl.h>
  8. #include <windows.h>
  9. #define DbgPrint printf
  10. #define SEG_1_SIZE 1024 * 1024
  11. #define SEG_X_SIZE 1024 * 1024 * 64
  12. #define VM_MEMMAN_ITERATIONS 150
  13. #define VM_MEMMAN_ITERATIONS2 2000
  14. #define MemManSubtest5Count 200
  15. int TotalBenchMarks = 0;
  16. #define MAX_BENCHMARKS 32
  17. char *BenchMarkNames[ MAX_BENCHMARKS ];
  18. ULONG BenchMarkRates[ MAX_BENCHMARKS ];
  19. ULONG BenchMarkFracs[ MAX_BENCHMARKS ];
  20. typedef struct _PERFINFO {
  21. LARGE_INTEGER StartTime;
  22. LARGE_INTEGER StopTime;
  23. PCHAR Title;
  24. ULONG Iterations;
  25. } PERFINFO, *PPERFINFO;
  26. int
  27. StartBenchMark(
  28. PCHAR Title,
  29. ULONG Iterations,
  30. PPERFINFO PerfInfo
  31. );
  32. VOID
  33. FinishBenchMark(
  34. PPERFINFO PerfInfo
  35. );
  36. __cdecl main()
  37. {
  38. PCHAR p1, p2, p3, p4; // pointers into new segment
  39. PCHAR pa[MemManSubtest5Count]; // array for section pointers
  40. PULONG u1;
  41. ULONG actual; // actual xfer count for read
  42. ULONG ssize; // section allocation size var
  43. ULONG ii, ix; // loop index variables
  44. PERFINFO PerfInfo;
  45. ULONG Seg1Size;
  46. ULONG SegxSize;
  47. ULONG CommitSize;
  48. NTSTATUS status;
  49. HANDLE CurrentProcessHandle, Section1;
  50. LARGE_INTEGER SectionSize;
  51. ULONG Size;
  52. ULONG ViewSize;
  53. DbgPrint("NT Memory Management test\n");
  54. CurrentProcessHandle = NtCurrentProcess();
  55. Size = 1024L * 1024L;
  56. p1 = NULL;
  57. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  58. (PVOID *)&p1,
  59. 0,
  60. &Size,
  61. MEM_RESERVE | MEM_COMMIT,
  62. PAGE_READWRITE);
  63. if (!NT_SUCCESS(status)) {
  64. DbgPrint("service failed allocvm - status %X\n", status);
  65. }
  66. for (p2=p1; p2 < (p1 + Size); p2 += 4) {
  67. u1 = (PULONG)p2;
  68. *u1 = (ULONG)p2;
  69. } // for
  70. SectionSize.LowPart = 1024*1024;
  71. SectionSize.HighPart = 0;
  72. status = NtCreateSection (&Section1,
  73. SECTION_MAP_READ | SECTION_MAP_WRITE,
  74. NULL,
  75. &SectionSize,
  76. PAGE_READWRITE,
  77. SEC_COMMIT,
  78. NULL);
  79. if (!NT_SUCCESS(status)) {
  80. DbgPrint("service failed create sect - status %X\n", status);
  81. }
  82. p3 = NULL;
  83. ViewSize = 0;
  84. status = NtMapViewOfSection (Section1,
  85. CurrentProcessHandle,
  86. (PVOID *)&p3,
  87. 0L,
  88. 0,
  89. NULL,
  90. &ViewSize,
  91. ViewUnmap,
  92. 0,
  93. PAGE_READWRITE );
  94. if (!NT_SUCCESS(status)) {
  95. DbgPrint("service failed mapview - status %X\n", status);
  96. }
  97. RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
  98. StartBenchMark( "NT MemMan00 -- 1 Meg Copy",
  99. 150,
  100. &PerfInfo
  101. );
  102. //
  103. // Memory Management sub-test 1 --
  104. //
  105. // Create a 1 MB segment with commitment of the pages,
  106. // then touch each page, which should cause a fault and
  107. // a demand zero page to be allocated.
  108. //
  109. //
  110. for (ii=0; ii<150; ii++) {
  111. RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
  112. }
  113. FinishBenchMark( &PerfInfo );
  114. status = NtClose (Section1);
  115. if (!NT_SUCCESS(status)) {
  116. DbgPrint("service failed close sect - status %X\n", status);
  117. }
  118. status = NtUnmapViewOfSection (CurrentProcessHandle,
  119. p3);
  120. if (!NT_SUCCESS(status)) {
  121. DbgPrint("service failed - status %X\n", status);
  122. }
  123. //
  124. // Memory Management sub-test 1 --
  125. //
  126. // Create a 1 MB segment with commitment of the pages,
  127. // then touch each page, which should cause a fault and
  128. // a demand zero page to be allocated.
  129. //
  130. //
  131. StartBenchMark( "NT MemMan01 -- create 1mb section, copy 1mb, delete",
  132. 150,
  133. &PerfInfo
  134. );
  135. for (ii=0; ii<150; ii++) {
  136. status = NtCreateSection (&Section1,
  137. SECTION_MAP_READ | SECTION_MAP_WRITE,
  138. NULL,
  139. &SectionSize,
  140. PAGE_READWRITE,
  141. SEC_COMMIT,
  142. NULL);
  143. if (!NT_SUCCESS(status)) {
  144. DbgPrint("service failed create sect - status %X\n", status);
  145. }
  146. p3 = NULL;
  147. ViewSize = 0;
  148. status = NtMapViewOfSection (Section1,
  149. CurrentProcessHandle,
  150. (PVOID *)&p3,
  151. 0L,
  152. 0,
  153. NULL,
  154. &ViewSize,
  155. ViewUnmap,
  156. 0,
  157. PAGE_READWRITE );
  158. if (!NT_SUCCESS(status)) {
  159. DbgPrint("service failed mapview - status %X\n", status);
  160. }
  161. RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
  162. p4 = NULL;
  163. ViewSize = 0;
  164. status = NtMapViewOfSection (Section1,
  165. CurrentProcessHandle,
  166. (PVOID *)&p4,
  167. 0L,
  168. 0,
  169. NULL,
  170. &ViewSize,
  171. ViewUnmap,
  172. 0,
  173. PAGE_READWRITE );
  174. if (!NT_SUCCESS(status)) {
  175. DbgPrint("service failed mapview - status %X\n", status);
  176. }
  177. status = NtClose (Section1);
  178. if (!NT_SUCCESS(status)) {
  179. DbgPrint("service failed close sect - status %X\n", status);
  180. }
  181. status = NtUnmapViewOfSection (CurrentProcessHandle,
  182. p3);
  183. if (!NT_SUCCESS(status)) {
  184. DbgPrint("service failed - status %X\n", status);
  185. }
  186. status = NtUnmapViewOfSection (CurrentProcessHandle,
  187. p4);
  188. if (!NT_SUCCESS(status)) {
  189. DbgPrint("service failed - status %X\n", status);
  190. }
  191. }
  192. FinishBenchMark( &PerfInfo );
  193. //
  194. // Memory Management sub-test 1 --
  195. //
  196. // Create a 1 MB segment with commitment of the pages,
  197. // then touch each page, which should cause a fault and
  198. // a demand zero page to be allocated.
  199. //
  200. //
  201. StartBenchMark( "NT MemMan02 -- alloc 1mb vm, copy 1mb, delete",
  202. 150,
  203. &PerfInfo
  204. );
  205. for (ii=0; ii<150; ii++) {
  206. Size = 1024*1024;
  207. p3 = NULL;
  208. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  209. (PVOID *)&p3,
  210. 0,
  211. &Size,
  212. MEM_RESERVE | MEM_COMMIT,
  213. PAGE_READWRITE);
  214. if (!NT_SUCCESS(status)) {
  215. DbgPrint("service failed allocvm - status %X\n", status);
  216. }
  217. RtlMoveMemory ((PVOID)p3, (PVOID)p1, Size);
  218. if (!NT_SUCCESS(status)) {
  219. DbgPrint("service failed close sect - status %X\n", status);
  220. }
  221. status = NtFreeVirtualMemory (CurrentProcessHandle,
  222. (PVOID *)&p3,
  223. &Size,
  224. MEM_RELEASE);
  225. if (!NT_SUCCESS(status)) {
  226. DbgPrint("service failed freevm - status %X\n", status);
  227. }
  228. }
  229. FinishBenchMark( &PerfInfo );
  230. status = NtFreeVirtualMemory (CurrentProcessHandle,
  231. (PVOID *)&p1,
  232. &Size,
  233. MEM_RELEASE);
  234. if (!NT_SUCCESS(status)) {
  235. DbgPrint("service failed freevm - status %X\n", status);
  236. }
  237. //
  238. // start regular benchmarks.
  239. //
  240. StartBenchMark( "NT MemMan1 -- 1 Meg Seg, Create, Commit & Touch",
  241. VM_MEMMAN_ITERATIONS,
  242. &PerfInfo
  243. );
  244. //
  245. // Memory Management sub-test 1 --
  246. //
  247. // Create a 1 MB segment with commitment of the pages,
  248. // then touch each page, which should cause a fault and
  249. // a demand zero page to be allocated.
  250. //
  251. //
  252. for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) {
  253. p1 = NULL;
  254. Seg1Size = SEG_1_SIZE;
  255. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  256. (PVOID *)&p1,
  257. 0,
  258. &Seg1Size,
  259. MEM_RESERVE | MEM_COMMIT,
  260. PAGE_READWRITE);
  261. if (!NT_SUCCESS(status)) {
  262. DbgPrint("service failed - status %lx\n", status);
  263. }
  264. for (p2=p1; p2 < (p1 + Seg1Size); p2 += 4096) {
  265. u1 = (PULONG)p2;
  266. *u1=99;
  267. // for (ix=0; ix<1023; ix++) {
  268. // u1++;
  269. // if (*u1 != 0) DbgPrint("%lx = %lx\n",u1,*u1);
  270. // }
  271. } // for
  272. status = NtFreeVirtualMemory (CurrentProcessHandle,
  273. (PVOID *)&p1,
  274. &Seg1Size,
  275. MEM_RELEASE);
  276. if (!NT_SUCCESS(status)) {
  277. DbgPrint("service failed - status %lx\n", status);
  278. }
  279. }
  280. FinishBenchMark( &PerfInfo );
  281. StartBenchMark( "NT MemMan1.5 -- 1 Meg Seg, Create, reserve Commit & Touch",
  282. VM_MEMMAN_ITERATIONS,
  283. &PerfInfo
  284. );
  285. //
  286. // Memory Management sub-test 1 --
  287. //
  288. // Create a 1 MB segment with commitment of the pages,
  289. // then touch each page, which should cause a fault and
  290. // a demand zero page to be allocated.
  291. //
  292. //
  293. for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) {
  294. p1 = NULL;
  295. Seg1Size = SEG_1_SIZE;
  296. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  297. (PVOID *)&p1,
  298. 0,
  299. &Seg1Size,
  300. MEM_RESERVE | MEM_COMMIT,
  301. PAGE_READONLY);
  302. if (!NT_SUCCESS(status)) {
  303. DbgPrint("service failed - status %lx\n", status);
  304. }
  305. status = NtProtectVirtualMemory (CurrentProcessHandle,
  306. (PVOID *)&p1,
  307. &Seg1Size,
  308. PAGE_READWRITE,
  309. &CommitSize);
  310. if (!NT_SUCCESS(status)) {
  311. DbgPrint("service failed (ntprotect)- status %lx\n", status);
  312. return 0;
  313. }
  314. for (p2=p1; p2 < (p1 + Seg1Size); p2 += 4096) {
  315. u1 = (PULONG)p2;
  316. *u1=99;
  317. // for (ix=0; ix<1023; ix++) {
  318. // u1++;
  319. // if (*u1 != 0) DbgPrint("%lx = %lx\n",u1,*u1);
  320. // }
  321. } // for
  322. status = NtFreeVirtualMemory (CurrentProcessHandle,
  323. (PVOID *)&p1,
  324. &Seg1Size,
  325. MEM_RELEASE);
  326. if (!NT_SUCCESS(status)) {
  327. DbgPrint("service failed - status %lx\n", status);
  328. }
  329. }
  330. FinishBenchMark( &PerfInfo );
  331. StartBenchMark( "NT MemMan2 -- 1 Meg Seg, Create & Commit Only",
  332. VM_MEMMAN_ITERATIONS2,
  333. &PerfInfo
  334. );
  335. //
  336. // Memory Management sub-test 2 --
  337. //
  338. // Create a 1 MB segment with commitment of the pages,
  339. // but never use the segment.
  340. //
  341. for (ii=0; ii<VM_MEMMAN_ITERATIONS2; ii++) {
  342. p1 = NULL;
  343. Seg1Size = SEG_1_SIZE;
  344. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  345. (PVOID *)&p1,
  346. 0,
  347. &Seg1Size,
  348. MEM_RESERVE | MEM_COMMIT,
  349. PAGE_READWRITE);
  350. if (!NT_SUCCESS(status)) {
  351. DbgPrint("service failed - status %lx\n", status);
  352. }
  353. status = NtFreeVirtualMemory (CurrentProcessHandle,
  354. (PVOID *)&p1,
  355. &Seg1Size,
  356. MEM_RELEASE);
  357. if (!NT_SUCCESS(status)) {
  358. DbgPrint("service failed - status %lx\n", status);
  359. }
  360. }
  361. FinishBenchMark( &PerfInfo );
  362. StartBenchMark( "NT MemMan3 -- 1 Meg Seg Create Only",
  363. VM_MEMMAN_ITERATIONS2,
  364. &PerfInfo
  365. );
  366. //
  367. // Memory Management sub-test 3 --
  368. //
  369. // Create a 1 MB segment without commitment of the pages,
  370. // but never use or commit the segment.
  371. //
  372. for (ii=0; ii<VM_MEMMAN_ITERATIONS2; ii++) {
  373. p1 = NULL;
  374. Seg1Size = SEG_1_SIZE;
  375. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  376. (PVOID *)&p1,
  377. 0,
  378. &Seg1Size,
  379. MEM_RESERVE,
  380. PAGE_READWRITE);
  381. if (!NT_SUCCESS(status)) {
  382. DbgPrint("service failed - status %lx\n", status);
  383. }
  384. status = NtFreeVirtualMemory (CurrentProcessHandle,
  385. (PVOID *)&p1,
  386. &Seg1Size,
  387. MEM_RELEASE);
  388. if (!NT_SUCCESS(status)) {
  389. DbgPrint("service failed - status %lx\n", status);
  390. }
  391. }
  392. FinishBenchMark( &PerfInfo );
  393. //
  394. // Reduce the number of iterations on this subtest for now.
  395. // When NT can perform it faster, up the interations again
  396. //
  397. #define VM_MMST04_ITERATIONS 4 //temporarily reduce the iterations
  398. StartBenchMark( "NT MemMan4 -- 64 Meg Seg, Commit Sparse",
  399. VM_MMST04_ITERATIONS,
  400. &PerfInfo
  401. );
  402. //
  403. // Memory Management sub-test 4 --
  404. //
  405. // Create a 64 MB segment without committing the pages,
  406. // then commit and touch at 128 KB intervals.
  407. //
  408. //
  409. for (ii=0; ii<VM_MMST04_ITERATIONS; ii++) {
  410. p1 = NULL;
  411. SegxSize = SEG_X_SIZE;
  412. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  413. (PVOID *)&p1,
  414. 0,
  415. &SegxSize,
  416. MEM_RESERVE,
  417. PAGE_READWRITE);
  418. if (!NT_SUCCESS(status)) {
  419. DbgPrint("service failed - status %lx\n", status);
  420. }
  421. CommitSize = 4;
  422. for (p2=p1; p2 < (p1 + SegxSize); p2 += 256 * 1024) {
  423. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  424. (PVOID *)&p2,
  425. 0,
  426. &CommitSize,
  427. MEM_COMMIT,
  428. PAGE_READWRITE);
  429. if (!NT_SUCCESS(status)) {
  430. DbgPrint("service failed - status %lx\n", status);
  431. }
  432. if (*p2 != 0) DbgPrint("%lx = %lx\n",p2,*p2);
  433. } // for
  434. status = NtFreeVirtualMemory (CurrentProcessHandle,
  435. (PVOID *)&p1,
  436. &SegxSize,
  437. MEM_RELEASE);
  438. if (!NT_SUCCESS(status)) {
  439. DbgPrint("service failed - status %lx\n", status);
  440. }
  441. }
  442. FinishBenchMark( &PerfInfo );
  443. //
  444. StartBenchMark( "NT MemMan5 -- Sparse Section Create/Delete Benchmark",
  445. VM_MEMMAN_ITERATIONS,
  446. &PerfInfo
  447. );
  448. //
  449. // Memory Management sub-test 5 --
  450. //
  451. // Create a alternatively 232k and 112 k memory sections.
  452. // For every 2 created, delete 1. Do this for MemManSubtest5Count times.
  453. //
  454. //
  455. for (ii=0; ii<VM_MEMMAN_ITERATIONS; ii++) {
  456. for (ix=0; ix<MemManSubtest5Count; ix++) {
  457. //
  458. // determine if even or odd allocation, if even and not 0, delete a section
  459. //
  460. ssize = (112 * 1024); //assume ODD allocation
  461. if ((ix & 1) == 0) { //if it is an even one
  462. ssize = (232 * 1024); //allocate 232 K on even passes
  463. if (ix){ //except on pass 0
  464. SegxSize = 0;
  465. status = NtFreeVirtualMemory (CurrentProcessHandle,
  466. (PVOID *)&pa[ix/2],
  467. &SegxSize,
  468. MEM_RELEASE);
  469. if (!NT_SUCCESS(status)) {
  470. DbgPrint("service failed - status %lx\n", status);
  471. }
  472. pa[ix / 2] = 0; //remember this one is gone
  473. }
  474. } // end if even allocation
  475. pa[ix] = NULL;
  476. status = NtAllocateVirtualMemory (CurrentProcessHandle,
  477. (PVOID *)&pa[ix],
  478. 0,
  479. &ssize,
  480. MEM_RESERVE,
  481. PAGE_READWRITE);
  482. if (!NT_SUCCESS(status)) {
  483. DbgPrint("service failed - status %lx\n", status);
  484. }
  485. } // for ix
  486. //
  487. // Now free up the memory used in this test
  488. //
  489. for (ix=0; ix<MemManSubtest5Count; ix++) {
  490. if (pa[ix] != 0) {
  491. SegxSize = 0;
  492. status = NtFreeVirtualMemory (CurrentProcessHandle,
  493. (PVOID *)&pa[ix],
  494. &SegxSize,
  495. MEM_RELEASE);
  496. if (!NT_SUCCESS(status)) {
  497. DbgPrint("service failed - status %lx\n", status);
  498. }
  499. } // if
  500. } // for
  501. } // for ii
  502. FinishBenchMark( &PerfInfo );
  503. DbgPrint("that's all\n");
  504. return (TRUE);
  505. }
  506. int
  507. StartBenchMark(
  508. PCHAR Title,
  509. ULONG Iterations,
  510. PPERFINFO PerfInfo
  511. )
  512. {
  513. DbgPrint( "*** Start %s (%d iterations)\n",
  514. PerfInfo->Title = Title,
  515. PerfInfo->Iterations = Iterations
  516. );
  517. NtQuerySystemTime( (PLARGE_INTEGER)&PerfInfo->StartTime );
  518. return( TRUE );
  519. }
  520. VOID
  521. FinishBenchMark(
  522. PPERFINFO PerfInfo
  523. )
  524. {
  525. ULONG TotalMilliSeconds;
  526. ULONG IterationsPerSecond;
  527. ULONG IterationFractions;
  528. LARGE_INTEGER Delta;
  529. NtQuerySystemTime( (PLARGE_INTEGER)&PerfInfo->StopTime );
  530. Delta.QuadPart = PerfInfo->StopTime.QuadPart -
  531. PerfInfo->StartTime.QuadPart;
  532. TotalMilliSeconds = Delta.LowPart / 10000;
  533. IterationsPerSecond = (1000 * PerfInfo->Iterations) / TotalMilliSeconds;
  534. IterationFractions = (1000 * PerfInfo->Iterations) % TotalMilliSeconds;
  535. IterationFractions = (1000 * IterationFractions) / TotalMilliSeconds;
  536. if (1) {
  537. DbgPrint( " iterations - %9d\n", PerfInfo->Iterations );
  538. DbgPrint( " milliseconds - %9d\n", TotalMilliSeconds );
  539. DbgPrint( " iterations/sec - %5d.%3d\n\n",
  540. IterationsPerSecond,
  541. IterationFractions
  542. );
  543. }
  544. BenchMarkNames[ TotalBenchMarks ] = PerfInfo->Title;
  545. BenchMarkRates[ TotalBenchMarks ] = IterationsPerSecond;
  546. BenchMarkFracs[ TotalBenchMarks ] = IterationFractions;
  547. TotalBenchMarks++;
  548. }