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.

709 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. perfmtr.c
  5. Abstract:
  6. This module contains the NT/Win32 Performance Meter
  7. Author:
  8. Mark Lucovsky (markl) 28-Mar-1991
  9. Revision History:
  10. --*/
  11. #include "perfmtrp.h"
  12. #define CPU_USAGE 0
  13. #define VM_USAGE 1
  14. #define POOL_USAGE 2
  15. #define IO_USAGE 3
  16. #define SRV_USAGE 4
  17. #define CACHE_READS 5
  18. #define VDM_USAGE 6
  19. #define FILE_CACHE 7
  20. #define RESIDENT_MEM 8
  21. //
  22. // Hi-Tech macro to figure out how much a field has changed by.
  23. //
  24. #define delta(FLD) (PerfInfo.FLD - PreviousPerfInfo.FLD)
  25. #define vdelta(FLD) (VdmInfo.FLD - PreviousVdmInfo.FLD)
  26. //
  27. // Delta combining Wait and NoWait cases.
  28. //
  29. #define deltac(FLD) (delta(FLD##Wait) + delta(FLD##NoWait))
  30. //
  31. // Hit Rate Macro (includes a rare trip to MulDivia...)
  32. //
  33. #define hitrate(FLD) (((Changes = delta(FLD)) == 0) ? 0 : \
  34. ((Changes < (Misses = delta(FLD##Miss))) ? 0 : \
  35. ((Changes - Misses) * 100 / Changes)))
  36. //
  37. // Hit Rate Macro combining Wait and NoWait cases
  38. //
  39. #define hitratec(FLD) (((Changes = deltac(FLD)) == 0) ? 0 : \
  40. ((Changes < (Misses = delta(FLD##WaitMiss) + delta(FLD##NoWaitMiss))) ? 0 : \
  41. ((Changes - Misses) * 100 / Changes)))
  42. //
  43. // Arbitrary percent calculation.
  44. //
  45. #define percent(PART,TOTAL) (((TOTAL) == 0) ? 0 : ((PART) * 100 / (TOTAL)))
  46. int
  47. __cdecl main( argc, argv )
  48. int argc;
  49. char *argv[];
  50. {
  51. SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
  52. SYSTEM_PERFORMANCE_INFORMATION PreviousPerfInfo;
  53. #ifdef i386
  54. SYSTEM_VDM_INSTEMUL_INFO VdmInfo;
  55. SYSTEM_VDM_INSTEMUL_INFO PreviousVdmInfo;
  56. #endif
  57. LARGE_INTEGER EndTime, BeginTime, ElapsedTime;
  58. ULONG DelayTimeMsec;
  59. ULONG DelayTimeTicks;
  60. ULONG PercentIdle;
  61. ULONG IdleDots;
  62. ULONG ProcessCount, ThreadCount, FileCount;
  63. ULONG Changes, Misses;
  64. POBJECT_TYPE_INFORMATION ObjectInfo;
  65. WCHAR Buffer[ 256 ];
  66. SYSTEM_FILECACHE_INFORMATION FileCacheInfo;
  67. SYSTEM_BASIC_INFORMATION BasicInfo;
  68. ULONG PreviousFileCacheFaultCount;
  69. BOOLEAN PrintHelp = TRUE;
  70. BOOLEAN PrintHeader = TRUE;
  71. ULONG DisplayType = CPU_USAGE;
  72. INPUT_RECORD InputRecord;
  73. HANDLE ScreenHandle;
  74. UCHAR LastKey;
  75. ULONG NumberOfInputRecords;
  76. SRV_STATISTICS ServerInfo;
  77. SRV_STATISTICS PreviousServerInfo;
  78. HANDLE ServerDeviceHandle = NULL;
  79. IO_STATUS_BLOCK IoStatusBlock;
  80. NTSTATUS Status;
  81. BOOLEAN ZeroServerStats;
  82. STRING DeviceName;
  83. UNICODE_STRING DeviceNameU;
  84. OBJECT_ATTRIBUTES ObjectAttributes;
  85. HANDLE NullDeviceHandle = NULL;
  86. DelayTimeMsec = 2500;
  87. DelayTimeTicks = DelayTimeMsec * 10000;
  88. RtlInitString( &DeviceName, "\\Device\\Null" );
  89. RtlAnsiStringToUnicodeString(&DeviceNameU, &DeviceName, TRUE);
  90. InitializeObjectAttributes(
  91. &ObjectAttributes,
  92. &DeviceNameU,
  93. OBJ_CASE_INSENSITIVE,
  94. NULL,
  95. NULL
  96. );
  97. Status = NtOpenFile(
  98. &NullDeviceHandle,
  99. SYNCHRONIZE,
  100. &ObjectAttributes,
  101. &IoStatusBlock,
  102. 0,
  103. FILE_SYNCHRONOUS_IO_NONALERT
  104. );
  105. RtlFreeUnicodeString(&DeviceNameU);
  106. if (NT_SUCCESS(Status)) {
  107. Status = IoStatusBlock.Status;
  108. }
  109. if (!NT_SUCCESS(Status)) {
  110. printf( "NtOpenFile (NULL device object) failed: %X\n", Status );
  111. return 0;
  112. }
  113. ScreenHandle = GetStdHandle (STD_INPUT_HANDLE);
  114. if (ScreenHandle == NULL) {
  115. printf("Error obtaining screen handle, error was: 0x%lx\n",
  116. GetLastError());
  117. return 0;
  118. }
  119. Status = NtQuerySystemInformation(
  120. SystemBasicInformation,
  121. &BasicInfo,
  122. sizeof(BasicInfo),
  123. NULL
  124. );
  125. if (NT_ERROR(Status)) {
  126. printf("Basic info failed x%lx\n",Status);
  127. return 0;
  128. }
  129. NtQuerySystemInformation(
  130. SystemPerformanceInformation,
  131. &PerfInfo,
  132. sizeof(PerfInfo),
  133. NULL
  134. );
  135. PreviousPerfInfo = PerfInfo;
  136. #ifdef i386
  137. NtQuerySystemInformation(
  138. SystemVdmInstemulInformation,
  139. &VdmInfo,
  140. sizeof(VdmInfo),
  141. NULL
  142. );
  143. PreviousVdmInfo = VdmInfo;
  144. #endif
  145. if ( argc > 1 ) {
  146. if ( argv[1][0] == '-' || argv[1][0] == '/') {
  147. switch ( argv[1][1] ) {
  148. case 'C':
  149. case 'c':
  150. DisplayType = CPU_USAGE;
  151. PrintHelp = FALSE;
  152. break;
  153. case 'F':
  154. case 'f':
  155. DisplayType = FILE_CACHE;
  156. PrintHelp = FALSE;
  157. PreviousFileCacheFaultCount = 0;
  158. break;
  159. case 'v':
  160. case 'V':
  161. DisplayType = VM_USAGE;
  162. PrintHelp = FALSE;
  163. break;
  164. case 'P':
  165. case 'p':
  166. DisplayType = POOL_USAGE;
  167. PrintHelp = FALSE;
  168. break;
  169. case 'I':
  170. case 'i':
  171. DisplayType = IO_USAGE;
  172. PrintHelp = FALSE;
  173. break;
  174. #ifdef i386
  175. case 'X':
  176. case 'x':
  177. DisplayType = VDM_USAGE;
  178. PrintHelp = FALSE;
  179. break;
  180. #endif
  181. case 'S':
  182. case 's':
  183. DisplayType = SRV_USAGE;
  184. PrintHelp = FALSE;
  185. ZeroServerStats = TRUE;
  186. break;
  187. case 'R':
  188. case 'r':
  189. DisplayType = CACHE_READS;
  190. PrintHelp = FALSE;
  191. break;
  192. case '?':
  193. default:
  194. PrintHelp = FALSE;
  195. printf("\nType :\n"
  196. "\t'C' for CPU usage\n"
  197. "\t'V' for VM usage\n"
  198. "\t'F' for File Cache usage\n"
  199. "\t'R' for Cache Manager reads and writes\n"
  200. "\t'P' for POOL usage\n"
  201. "\t'I' for I/O usage\n"
  202. #ifdef i386
  203. "\t'X' for x86 Vdm Stats\n"
  204. #endif
  205. "\t'S' for Server Stats\n"
  206. "\t'H' for header\n"
  207. "\t'Q' to quit\n\n");
  208. }
  209. }
  210. }
  211. while(TRUE) {
  212. while (WaitForSingleObject( ScreenHandle, DelayTimeMsec ) == STATUS_WAIT_0) {
  213. //
  214. // Check for input record
  215. //
  216. if (ReadConsoleInput( ScreenHandle, &InputRecord, 1, &NumberOfInputRecords ) &&
  217. InputRecord.EventType == KEY_EVENT &&
  218. InputRecord.Event.KeyEvent.bKeyDown
  219. ) {
  220. LastKey = InputRecord.Event.KeyEvent.uChar.AsciiChar;
  221. //
  222. // Ignore control characters.
  223. //
  224. if (LastKey >= ' ') {
  225. switch (toupper( LastKey )) {
  226. case 'C':
  227. DisplayType = CPU_USAGE;
  228. PrintHeader = TRUE;
  229. PrintHelp = FALSE;
  230. break;
  231. case 'F':
  232. DisplayType = FILE_CACHE;
  233. PrintHeader = TRUE;
  234. PrintHelp = FALSE;
  235. PreviousFileCacheFaultCount = 0;
  236. break;
  237. case 'H':
  238. PrintHeader = TRUE;
  239. PrintHelp = FALSE;
  240. break;
  241. case 'V':
  242. DisplayType = VM_USAGE;
  243. PrintHeader = TRUE;
  244. PrintHelp = FALSE;
  245. PreviousPerfInfo = PerfInfo;
  246. break;
  247. case 'P':
  248. DisplayType = POOL_USAGE;
  249. PrintHeader = TRUE;
  250. PrintHelp = FALSE;
  251. break;
  252. case 'I':
  253. DisplayType = IO_USAGE;
  254. PrintHeader = TRUE;
  255. PrintHelp = FALSE;
  256. break;
  257. #ifdef i386
  258. case 'X':
  259. DisplayType = VDM_USAGE;
  260. PrintHeader = TRUE;
  261. PrintHelp = FALSE;
  262. break;
  263. #endif
  264. case 'S':
  265. DisplayType = SRV_USAGE;
  266. PrintHeader = TRUE;
  267. PrintHelp = FALSE;
  268. ZeroServerStats = TRUE;
  269. break;
  270. case 'R':
  271. DisplayType = CACHE_READS;
  272. PrintHeader = TRUE;
  273. PrintHelp = FALSE;
  274. break;
  275. case 'Q':
  276. if (ServerDeviceHandle != NULL) {
  277. NtClose(ServerDeviceHandle);
  278. }
  279. ExitProcess(0);
  280. default:
  281. break;
  282. }
  283. }
  284. }
  285. }
  286. if (PrintHelp) {
  287. printf("\nType :\n"
  288. "\t'C' for CPU usage\n"
  289. "\t'V' for VM usage\n"
  290. "\t'F' for File Cache usage\n"
  291. "\t'R' for Cache Manager reads and writes\n"
  292. "\t'P' for POOL usage\n"
  293. "\t'I' for I/O usage\n"
  294. #ifdef i386
  295. "\t'X' for x86 Vdm Stats\n"
  296. #endif
  297. "\t'S' for Server Stats\n"
  298. "\t'H' for header\n"
  299. "\t'Q' to quit\n\n");
  300. PrintHelp = FALSE;
  301. }
  302. NtQuerySystemInformation(
  303. SystemPerformanceInformation,
  304. &PerfInfo,
  305. sizeof(PerfInfo),
  306. NULL
  307. );
  308. #ifdef i386
  309. NtQuerySystemInformation(
  310. SystemVdmInstemulInformation,
  311. &VdmInfo,
  312. sizeof(VdmInfo),
  313. NULL
  314. );
  315. #endif
  316. ObjectInfo = (POBJECT_TYPE_INFORMATION)Buffer;
  317. NtQueryObject( NtCurrentProcess(),
  318. ObjectTypeInformation,
  319. ObjectInfo,
  320. sizeof( Buffer ),
  321. NULL
  322. );
  323. ProcessCount = ObjectInfo->TotalNumberOfObjects;
  324. NtQueryObject( NtCurrentThread(),
  325. ObjectTypeInformation,
  326. ObjectInfo,
  327. sizeof( Buffer ),
  328. NULL
  329. );
  330. ThreadCount = ObjectInfo->TotalNumberOfObjects;
  331. NtQueryObject( NullDeviceHandle,
  332. ObjectTypeInformation,
  333. ObjectInfo,
  334. sizeof( Buffer ),
  335. NULL
  336. );
  337. FileCount = ObjectInfo->TotalNumberOfObjects;
  338. switch (DisplayType) {
  339. case CPU_USAGE:
  340. EndTime = *(PLARGE_INTEGER)&PerfInfo.IdleProcessTime;
  341. BeginTime = *(PLARGE_INTEGER)&PreviousPerfInfo.IdleProcessTime;
  342. ElapsedTime.QuadPart = EndTime.QuadPart - BeginTime.QuadPart;
  343. PercentIdle = ((ElapsedTime.LowPart/BasicInfo.NumberOfProcessors)*100) / DelayTimeTicks;
  344. //
  345. // Sometimes it takes significantly longer than 2.5 seconds
  346. // to make a round trip.
  347. //
  348. if ( PercentIdle > 100 ) {
  349. PercentIdle = 100;
  350. }
  351. IdleDots = DOT_BUFF_LEN - (PercentIdle / 10 );
  352. memset(DotBuff,' ',DOT_BUFF_LEN);
  353. DotBuff[DOT_BUFF_LEN] = '|';
  354. DotBuff[DOT_BUFF_LEN+1] = '\0';
  355. memset(DotBuff,DOT_CHAR,IdleDots);
  356. if (PrintHeader) {
  357. printf("CPU Usage Page Page Page InCore NonP Pgd Incore Pgd Incore Incore Proc Thd\n");
  358. printf(" Flts Aval Pool PgPool Pool Krnl Krnl Drvr Drvr Cache Cnt Cnt\n");
  359. PrintHeader = FALSE;
  360. }
  361. printf( "%s", DotBuff );
  362. printf( "%4ld %4ld %4ld (%4ld) %4ld %4ld (%4ld) %4ld (%4ld) (%4ld) %3ld %4ld\n",
  363. PerfInfo.PageFaultCount - PreviousPerfInfo.PageFaultCount,
  364. PerfInfo.AvailablePages,
  365. PerfInfo.PagedPoolPages,
  366. PerfInfo.ResidentPagedPoolPage,
  367. PerfInfo.NonPagedPoolPages,
  368. PerfInfo.TotalSystemCodePages,
  369. PerfInfo.ResidentSystemCodePage,
  370. PerfInfo.TotalSystemDriverPages,
  371. PerfInfo.ResidentSystemDriverPage,
  372. PerfInfo.ResidentSystemCachePage,
  373. ProcessCount,
  374. ThreadCount
  375. );
  376. break;
  377. case VM_USAGE:
  378. if (PrintHeader) {
  379. printf("avail page COW Tran Cache Demd Read Read Cache Cache Page Write Map Map\n");
  380. printf("pages faults Tran zero flts I/Os flts I/Os writ I/Os write I/O\n");
  381. PrintHeader = FALSE;
  382. }
  383. printf( "%5ld %5ld %4ld %5ld %5ld %5ld %5ld %5ld %5ld%5ld%5ld%5ld%6ld%5ld\n",
  384. PerfInfo.AvailablePages,
  385. PerfInfo.PageFaultCount - PreviousPerfInfo.PageFaultCount,
  386. PerfInfo.CopyOnWriteCount - PreviousPerfInfo.CopyOnWriteCount,
  387. PerfInfo.TransitionCount - PreviousPerfInfo.TransitionCount,
  388. PerfInfo.CacheTransitionCount - PreviousPerfInfo.CacheTransitionCount,
  389. PerfInfo.DemandZeroCount - PreviousPerfInfo.DemandZeroCount,
  390. PerfInfo.PageReadCount - PreviousPerfInfo.PageReadCount,
  391. PerfInfo.PageReadIoCount - PreviousPerfInfo.PageReadIoCount,
  392. PerfInfo.CacheReadCount - PreviousPerfInfo.CacheReadCount,
  393. PerfInfo.CacheIoCount - PreviousPerfInfo.CacheIoCount,
  394. PerfInfo.DirtyPagesWriteCount - PreviousPerfInfo.DirtyPagesWriteCount,
  395. PerfInfo.DirtyWriteIoCount - PreviousPerfInfo.DirtyWriteIoCount,
  396. PerfInfo.MappedPagesWriteCount - PreviousPerfInfo.MappedPagesWriteCount,
  397. PerfInfo.MappedWriteIoCount - PreviousPerfInfo.MappedWriteIoCount
  398. );
  399. break;
  400. case CACHE_READS:
  401. if (PrintHeader) {
  402. PrintHeader = FALSE;
  403. printf(" Map Cnv Pin Copy Mdl Read Fast Fast Fast Lazy Lazy\n");
  404. printf(" Read To Read Read Read Ahed Read Read Read Wrts Wrt\n");
  405. printf(" Hit Pin Hit Hit Hit I/Os Calls Resc Not I/Os Pgs\n");
  406. printf("Count Rate Rate Count Rate Count Rate Count Rate Miss Poss \n");
  407. }
  408. printf("%05ld %4ld %4ld %05ld %4ld %05ld %4ld %05ld %4ld %4ld %5ld %4ld %4ld %4ld %4ld\n",
  409. deltac(CcMapData),
  410. hitratec(CcMapData),
  411. percent(delta(CcPinMappedDataCount),deltac(CcMapData)),
  412. deltac(CcPinRead),
  413. hitratec(CcPinRead),
  414. deltac(CcCopyRead),
  415. hitratec(CcCopyRead),
  416. deltac(CcMdlRead),
  417. hitratec(CcMdlRead),
  418. delta(CcReadAheadIos),
  419. deltac(CcFastRead),
  420. delta(CcFastReadResourceMiss),
  421. delta(CcFastReadNotPossible),
  422. delta(CcLazyWriteIos),
  423. delta(CcLazyWritePages));
  424. break;
  425. #ifdef i386
  426. case VDM_USAGE:
  427. if (PrintHeader) {
  428. PrintHeader = FALSE;
  429. printf("PUSHF POPF IRET HLT CLI STI BOP SEGNOTP\n");
  430. }
  431. printf("%5d %5d %5d %5d %5d %5d %5d %7d\n",
  432. vdelta(OpcodePUSHF),
  433. vdelta(OpcodePOPF),
  434. vdelta(OpcodeIRET),
  435. vdelta(OpcodeHLT),
  436. vdelta(OpcodeCLI),
  437. vdelta(OpcodeSTI),
  438. vdelta(BopCount),
  439. vdelta(SegmentNotPresent)
  440. );
  441. break;
  442. #endif
  443. case POOL_USAGE:
  444. if (PrintHeader) {
  445. printf("Paged Paged Paged Non Non Non Page Paged Non Commit Commit SysPte\n");
  446. printf("Alloc Freed A-F Alloc Freed A-F Aval Pages Pages Pages Limit Free\n");
  447. PrintHeader = FALSE;
  448. }
  449. printf( "%5ld %5ld %5ld %5ld %5ld %5ld %5ld %5ld %5ld %6ld %6ld %7ld\n",
  450. PerfInfo.PagedPoolAllocs - PreviousPerfInfo.PagedPoolAllocs,
  451. PerfInfo.PagedPoolFrees - PreviousPerfInfo.PagedPoolFrees,
  452. PerfInfo.PagedPoolAllocs - PerfInfo.PagedPoolFrees,
  453. PerfInfo.NonPagedPoolAllocs - PreviousPerfInfo.NonPagedPoolAllocs,
  454. PerfInfo.NonPagedPoolFrees - PreviousPerfInfo.NonPagedPoolFrees,
  455. PerfInfo.NonPagedPoolAllocs - PerfInfo.NonPagedPoolFrees,
  456. PerfInfo.AvailablePages,
  457. PerfInfo.PagedPoolPages,
  458. PerfInfo.NonPagedPoolPages,
  459. PerfInfo.CommittedPages,
  460. PerfInfo.CommitLimit,
  461. PerfInfo.FreeSystemPtes
  462. );
  463. break;
  464. case IO_USAGE:
  465. if (PrintHeader) {
  466. printf(" Read Write Other Read Write Other File File\n");
  467. printf(" I/Os I/Os I/Os Xfer Xfer Xfer Objects Handles\n");
  468. PrintHeader = FALSE;
  469. }
  470. printf( "%5ld %5ld %5ld %8ld %8ld %8ld %8ld %8ld\n",
  471. PerfInfo.IoReadOperationCount - PreviousPerfInfo.IoReadOperationCount,
  472. PerfInfo.IoWriteOperationCount - PreviousPerfInfo.IoWriteOperationCount,
  473. PerfInfo.IoOtherOperationCount - PreviousPerfInfo.IoOtherOperationCount,
  474. PerfInfo.IoReadTransferCount.QuadPart -
  475. PreviousPerfInfo.IoReadTransferCount.QuadPart,
  476. PerfInfo.IoWriteTransferCount.QuadPart -
  477. PreviousPerfInfo.IoWriteTransferCount.QuadPart,
  478. PerfInfo.IoOtherTransferCount.QuadPart -
  479. PreviousPerfInfo.IoOtherTransferCount.QuadPart,
  480. FileCount,
  481. ObjectInfo->TotalNumberOfHandles
  482. );
  483. break;
  484. case SRV_USAGE:
  485. if (ServerDeviceHandle == NULL) {
  486. RtlInitString( &DeviceName, SERVER_DEVICE_NAME );
  487. RtlAnsiStringToUnicodeString(&DeviceNameU, &DeviceName, TRUE);
  488. InitializeObjectAttributes(
  489. &ObjectAttributes,
  490. &DeviceNameU,
  491. OBJ_CASE_INSENSITIVE,
  492. NULL,
  493. NULL
  494. );
  495. Status = NtOpenFile(
  496. &ServerDeviceHandle,
  497. SYNCHRONIZE,
  498. &ObjectAttributes,
  499. &IoStatusBlock,
  500. 0,
  501. FILE_SYNCHRONOUS_IO_NONALERT
  502. );
  503. RtlFreeUnicodeString(&DeviceNameU);
  504. if (NT_SUCCESS(Status)) {
  505. Status = IoStatusBlock.Status;
  506. }
  507. if (!NT_SUCCESS(Status)) {
  508. printf( "NtOpenFile (server device object) failed: %X\n", Status );
  509. break;
  510. }
  511. }
  512. Status = NtFsControlFile(
  513. ServerDeviceHandle,
  514. NULL,
  515. NULL,
  516. NULL,
  517. &IoStatusBlock,
  518. FSCTL_SRV_GET_STATISTICS,
  519. NULL, 0,
  520. &ServerInfo, sizeof(ServerInfo)
  521. );
  522. if (NT_SUCCESS(Status)) {
  523. Status = IoStatusBlock.Status;
  524. }
  525. if (!NT_SUCCESS(Status)) {
  526. printf( "NtFsControlFile failed: %X\n", Status );
  527. ServerDeviceHandle = NULL;
  528. break;
  529. }
  530. if (PrintHeader) {
  531. printf( " Bytes Bytes Paged NonPaged Logn WItm\n");
  532. printf( " Rcvd Sent Pool Pool Sess File Srch Errs Shtg\n");
  533. PrintHeader = FALSE;
  534. }
  535. if (ZeroServerStats) {
  536. PreviousServerInfo = ServerInfo;
  537. ZeroServerStats = FALSE;
  538. }
  539. {
  540. LARGE_INTEGER BytesReceived, BytesSent;
  541. BytesReceived.QuadPart =
  542. ServerInfo.TotalBytesReceived.QuadPart -
  543. PreviousServerInfo.TotalBytesReceived.QuadPart;
  544. BytesSent.QuadPart =
  545. ServerInfo.TotalBytesSent.QuadPart -
  546. PreviousServerInfo.TotalBytesSent.QuadPart;
  547. printf( "%7ld %7ld %8ld %8ld %4ld %4ld %4ld %4ld %4ld\n",
  548. BytesReceived.LowPart,
  549. BytesSent.LowPart,
  550. ServerInfo.CurrentPagedPoolUsage,
  551. ServerInfo.CurrentNonPagedPoolUsage,
  552. ServerInfo.CurrentNumberOfSessions,
  553. ServerInfo.CurrentNumberOfOpenFiles,
  554. ServerInfo.CurrentNumberOfOpenSearches,
  555. ServerInfo.LogonErrors,
  556. ServerInfo.WorkItemShortages
  557. );
  558. }
  559. PreviousServerInfo = ServerInfo;
  560. break;
  561. case FILE_CACHE:
  562. if (PrintHeader) {
  563. printf("Avail Page Current Peak Fault Fault\n");
  564. printf("Pages Faults Size Kb Size Total Count\n");
  565. PrintHeader = FALSE;
  566. }
  567. NtQuerySystemInformation(
  568. SystemFileCacheInformation,
  569. &FileCacheInfo,
  570. sizeof(FileCacheInfo),
  571. NULL
  572. );
  573. printf( "%5ld %5ld %7ld %7ld %8ld %8ld\n",
  574. PerfInfo.AvailablePages,
  575. PerfInfo.PageFaultCount - PreviousPerfInfo.PageFaultCount,
  576. FileCacheInfo.CurrentSize / 1024,
  577. FileCacheInfo.PeakSize / 1024,
  578. FileCacheInfo.PageFaultCount,
  579. FileCacheInfo.PageFaultCount - PreviousFileCacheFaultCount
  580. );
  581. PreviousFileCacheFaultCount = FileCacheInfo.PageFaultCount;
  582. break;
  583. }
  584. PreviousPerfInfo = PerfInfo;
  585. #ifdef i386
  586. PreviousVdmInfo = VdmInfo;
  587. #endif
  588. }
  589. }