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.

845 lines
29 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. #include <..\ztools\inc\tools.h>
  10. #define NUMBER_SERVICE_TABLES 2
  11. #define BUFFER_SIZE 1024
  12. VOID
  13. SortUlongData (
  14. IN ULONG Count,
  15. IN ULONG Index[],
  16. IN ULONG Data[]
  17. );
  18. extern UCHAR *CallTable[];
  19. ULONG SystemCallBufferStart[BUFFER_SIZE];
  20. ULONG SystemCallBufferDone[BUFFER_SIZE];
  21. ULONG Index[BUFFER_SIZE];
  22. ULONG CallData[BUFFER_SIZE];
  23. #define MAX_PROCESSOR 16
  24. SYSTEM_BASIC_INFORMATION BasicInfo;
  25. SYSTEM_PERFORMANCE_INFORMATION SystemInfoStart;
  26. SYSTEM_PERFORMANCE_INFORMATION SystemInfoDone;
  27. SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorInfoStart[MAX_PROCESSOR];
  28. SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorInfoDone[MAX_PROCESSOR];
  29. #define vdelta(FLD) (VdmInfoDone.FLD - VdmInfoStart.FLD)
  30. #ifdef i386
  31. SYSTEM_VDM_INSTEMUL_INFO VdmInfoStart;
  32. SYSTEM_VDM_INSTEMUL_INFO VdmInfoDone;
  33. #endif
  34. HANDLE
  35. GetServerProcessHandle( VOID )
  36. {
  37. HANDLE Process;
  38. OBJECT_ATTRIBUTES Obja;
  39. UNICODE_STRING Unicode;
  40. NTSTATUS Status;
  41. RtlInitUnicodeString(&Unicode, L"\\WindowsSS");
  42. InitializeObjectAttributes(
  43. &Obja,
  44. &Unicode,
  45. 0,
  46. NULL,
  47. NULL
  48. );
  49. Status = NtOpenProcess(
  50. &Process,
  51. PROCESS_ALL_ACCESS,
  52. &Obja,
  53. NULL
  54. );
  55. if ( !NT_SUCCESS(Status) ) {
  56. printf("OpenProcess Failed %lx\n",Status);
  57. Process = NULL;
  58. }
  59. return Process;
  60. }
  61. BOOL WINAPI
  62. CtrlcHandler(
  63. ULONG CtrlType
  64. )
  65. {
  66. //
  67. // Ignore control C interrupts. Let child process deal with them
  68. // if it wants. If it doesn't then it will terminate and we will
  69. // get control and terminate ourselves
  70. //
  71. return TRUE;
  72. }
  73. int
  74. __cdecl main(
  75. int argc,
  76. char *argv[],
  77. char *envp[]
  78. )
  79. {
  80. LPSTR s;
  81. BOOL bFull;
  82. BOOL bOneLine;
  83. BOOL bSyscall;
  84. STARTUPINFO StartupInfo;
  85. PROCESS_INFORMATION ProcessInformation;
  86. BOOL b;
  87. VM_COUNTERS ServerVmInfoStart, ServerVmInfoDone, ProcessVmInfoStart, ProcessVmInfoDone;
  88. KERNEL_USER_TIMES Times, ServerStart, ServerDone, ProcessStart, ProcessDone;
  89. NTSTATUS Status;
  90. TIME_FIELDS Etime,Utime,Ktime,Itime;
  91. LARGE_INTEGER RunTime;
  92. LARGE_INTEGER IdleTime;
  93. HANDLE OtherProcess;
  94. ULONG i;
  95. CHAR ch;
  96. ULONG ProcessId;
  97. HANDLE ProcessHandle;
  98. ULONG Temp;
  99. ULONG ContextSwitches;
  100. ULONG FirstLevelFills;
  101. ULONG SecondLevelFills;
  102. PSYSTEM_CALL_COUNT_INFORMATION SystemCallInfoStart;
  103. PSYSTEM_CALL_COUNT_INFORMATION SystemCallInfoDone;
  104. PULONG SystemCallTableStart;
  105. PULONG SystemCallTableDone;
  106. ULONG NumberOfCounts;
  107. PULONG p;
  108. BOOL bShowHelpMsg = FALSE;
  109. argv;
  110. envp;
  111. ConvertAppToOem( argc, argv );
  112. OtherProcess = NULL;
  113. ProcessHandle = NULL;
  114. if ( (argc < 2) ) {
  115. bShowHelpMsg = TRUE;
  116. }
  117. SetConsoleCtrlHandler( CtrlcHandler, TRUE );
  118. ProcessId = 0;
  119. s = GetCommandLine();
  120. if( s != NULL ) {
  121. CharToOem( s, s );
  122. }
  123. bFull = FALSE;
  124. bOneLine = FALSE;
  125. bSyscall = FALSE;
  126. //
  127. // skip blanks
  128. //
  129. while( (NULL != s) && (*s > ' '))s++;
  130. //
  131. // get to next token
  132. //
  133. while((NULL != s) && (*s == ' ')) s++;
  134. while ((NULL != s) && ( *s == '-' ) || ( *s == '/' )) {
  135. s++;
  136. //if "-" or "/" only specified.. display help/usage
  137. if ( '\0' == *s )
  138. {
  139. bShowHelpMsg = TRUE;
  140. break;
  141. }
  142. while (*s > ' ') {
  143. switch (*s) {
  144. case '1' :
  145. bOneLine = TRUE;
  146. break;
  147. case 'c' :
  148. case 'C' :
  149. bSyscall = TRUE;
  150. break;
  151. case 'f' :
  152. case 'F' :
  153. bFull = TRUE;
  154. break;
  155. case 's' :
  156. case 'S' :
  157. OtherProcess = GetServerProcessHandle();
  158. break;
  159. case 'P':
  160. case 'p':
  161. // pid takes decimal argument
  162. s++;
  163. do
  164. ch = *s++;
  165. while (ch == ' ' || ch == '\t');
  166. while (ch >= '0' && ch <= '9') {
  167. Temp = ProcessId * 10 + ch - '0';
  168. if (Temp < ProcessId) {
  169. printf("pid number overflow\n");
  170. ExitProcess(1);
  171. }
  172. ProcessId = Temp;
  173. ch = *s++;
  174. }
  175. if (!ProcessId) {
  176. printf("bad pid '%ld'\n", ProcessId);
  177. ExitProcess(1);
  178. }
  179. s--;
  180. if ( *s == ' ' ) s--;
  181. break;
  182. case 'h':
  183. case 'H':
  184. case '?':
  185. bShowHelpMsg = TRUE;
  186. break;
  187. default :
  188. break;
  189. }
  190. s++;
  191. }
  192. //
  193. // get to next token
  194. //
  195. while(*s==' ')s++;
  196. }
  197. // see if this is just a request for command line help.
  198. if ( bShowHelpMsg ) {
  199. puts("\n"
  200. "Usage: ntimer [-1 -f -s] name-of-image [parameters]...\n"
  201. "\n"
  202. " Displays the Elapsed, Kernel, User and Idle time of the\n"
  203. " image specified in the command line\n"
  204. "\n"
  205. " -1 displays output on one line\n"
  206. " -f displays the process page faults, total\n"
  207. " system interrupts, context switches and system\n"
  208. " calls\n"
  209. " -s indicates the name of the image is that of a\n"
  210. " server process. Press Ctrl-C to get the times.");
  211. ExitProcess(1);
  212. }
  213. if ( ProcessId ) {
  214. ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessId);
  215. }
  216. memset(&StartupInfo,0,sizeof(StartupInfo));
  217. StartupInfo.cb = sizeof(StartupInfo);
  218. if (bOneLine) {
  219. bSyscall = FALSE;
  220. }
  221. if (bSyscall) {
  222. Status = NtQuerySystemInformation(SystemCallCountInformation,
  223. (PVOID)SystemCallBufferStart,
  224. BUFFER_SIZE * sizeof(ULONG),
  225. NULL);
  226. bSyscall = FALSE;
  227. if (!NT_SUCCESS(Status)) {
  228. printf("Failed to query system call performance information: %x\n", Status);
  229. } else {
  230. SystemCallInfoStart = (PVOID)SystemCallBufferStart;
  231. SystemCallInfoDone = (PVOID)SystemCallBufferDone;
  232. //
  233. // Make sure that the number of tables reported by the kernel matches
  234. // our list.
  235. //
  236. if (SystemCallInfoStart->NumberOfTables != NUMBER_SERVICE_TABLES) {
  237. printf("System call table count (%d) doesn't match NTIMER's count (%d)\n",
  238. SystemCallInfoStart->NumberOfTables, NUMBER_SERVICE_TABLES);
  239. } else {
  240. //
  241. // Make sure call count information is available for base services.
  242. //
  243. p = (PULONG)(SystemCallInfoStart + 1);
  244. SystemCallTableStart = (PULONG)(SystemCallInfoStart + 1) + NUMBER_SERVICE_TABLES;
  245. SystemCallTableDone = (PULONG)(SystemCallInfoDone + 1) + NUMBER_SERVICE_TABLES;
  246. if (p[0] == 0) {
  247. printf("No system call count information available for base services\n");
  248. } else {
  249. //
  250. // If there is a hole in the count information (i.e., one set of services
  251. // doesn't have counting enabled, but a subsequent one does, then our
  252. // indexes will be off, and we'll display the wrong service names.
  253. //
  254. i = 2;
  255. for ( ; i < NUMBER_SERVICE_TABLES; i++ ) {
  256. if ((p[i] != 0) && (p[i-1] == 0)) {
  257. printf("One or more call count tables empty. NTIMER can't report\n");
  258. break;
  259. }
  260. }
  261. if ( i >= NUMBER_SERVICE_TABLES ) {
  262. bSyscall = TRUE;
  263. NumberOfCounts = SystemCallInfoStart->Length
  264. - sizeof(SYSTEM_CALL_COUNT_INFORMATION)
  265. - NUMBER_SERVICE_TABLES * sizeof(ULONG);
  266. }
  267. }
  268. }
  269. }
  270. }
  271. if ( OtherProcess ) {
  272. Status = NtQueryInformationProcess(
  273. OtherProcess,
  274. ProcessTimes,
  275. &ServerStart,
  276. sizeof(Times),
  277. NULL
  278. );
  279. if ( !NT_SUCCESS(Status) ) {
  280. ExitProcess((DWORD)Status);
  281. }
  282. }
  283. if ( ProcessHandle ) {
  284. Status = NtQueryInformationProcess(
  285. ProcessHandle,
  286. ProcessTimes,
  287. &ProcessStart,
  288. sizeof(Times),
  289. NULL
  290. );
  291. if ( !NT_SUCCESS(Status) ) {
  292. ExitProcess((DWORD)Status);
  293. }
  294. }
  295. if ( bFull ) {
  296. if ( OtherProcess ) {
  297. Status = NtQueryInformationProcess(
  298. OtherProcess,
  299. ProcessVmCounters,
  300. &ServerVmInfoStart,
  301. sizeof(VM_COUNTERS),
  302. NULL
  303. );
  304. if ( !NT_SUCCESS(Status) ) {
  305. ExitProcess((DWORD)Status);
  306. }
  307. }
  308. if ( ProcessHandle ) {
  309. Status = NtQueryInformationProcess(
  310. ProcessHandle,
  311. ProcessVmCounters,
  312. &ProcessVmInfoStart,
  313. sizeof(VM_COUNTERS),
  314. NULL
  315. );
  316. if ( !NT_SUCCESS(Status) ) {
  317. ExitProcess((DWORD)Status);
  318. }
  319. }
  320. else {
  321. ZeroMemory(&ProcessVmInfoStart,sizeof(VM_COUNTERS));
  322. }
  323. #ifdef i386
  324. Status = NtQuerySystemInformation(
  325. SystemVdmInstemulInformation,
  326. &VdmInfoStart,
  327. sizeof(VdmInfoStart),
  328. NULL
  329. );
  330. if (!NT_SUCCESS(Status)) {
  331. printf("Failed to query vdm information\n");
  332. ExitProcess((DWORD)Status);
  333. }
  334. #endif
  335. Status = NtQuerySystemInformation(
  336. SystemBasicInformation,
  337. &BasicInfo,
  338. sizeof(BasicInfo),
  339. NULL
  340. );
  341. if (!NT_SUCCESS(Status)) {
  342. printf("Failed to query basic information\n");
  343. ExitProcess((DWORD)Status);
  344. }
  345. Status = NtQuerySystemInformation(SystemProcessorPerformanceInformation,
  346. (PVOID)&ProcessorInfoStart,
  347. sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * MAX_PROCESSOR,
  348. NULL);
  349. if (!NT_SUCCESS(Status)) {
  350. printf("Failed to query preocessor performance information\n");
  351. ExitProcess((DWORD)Status);
  352. }
  353. }
  354. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  355. (PVOID)&SystemInfoStart,
  356. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  357. NULL);
  358. ContextSwitches = SystemInfoStart.ContextSwitches;
  359. FirstLevelFills = SystemInfoStart.FirstLevelTbFills;
  360. SecondLevelFills = SystemInfoStart.SecondLevelTbFills;
  361. b = CreateProcess(
  362. NULL,
  363. s,
  364. NULL,
  365. NULL,
  366. TRUE,
  367. 0,
  368. NULL,
  369. NULL,
  370. &StartupInfo,
  371. &ProcessInformation
  372. );
  373. if ( !b ) {
  374. printf("CreateProcess(%s) failed %d\n",s,GetLastError());
  375. ExitProcess(GetLastError());
  376. }
  377. WaitForSingleObject(ProcessInformation.hProcess,(DWORD)-1);
  378. Status = NtQuerySystemInformation(SystemPerformanceInformation,
  379. (PVOID)&SystemInfoDone,
  380. sizeof(SYSTEM_PERFORMANCE_INFORMATION),
  381. NULL);
  382. if (!bOneLine) {
  383. printf("\nContextSwitches - %d\nFirst level fills = %d\nSecond level fills = %d\n",
  384. SystemInfoDone.ContextSwitches - ContextSwitches,
  385. SystemInfoDone.FirstLevelTbFills - FirstLevelFills,
  386. SystemInfoDone.SecondLevelTbFills - SecondLevelFills);
  387. }
  388. if ( OtherProcess ) {
  389. Status = NtQueryInformationProcess(
  390. OtherProcess,
  391. ProcessTimes,
  392. &ServerDone,
  393. sizeof(Times),
  394. NULL
  395. );
  396. if ( !NT_SUCCESS(Status) ) {
  397. ExitProcess((DWORD)Status);
  398. }
  399. }
  400. if ( ProcessHandle ) {
  401. Status = NtQueryInformationProcess(
  402. ProcessHandle,
  403. ProcessTimes,
  404. &ProcessDone,
  405. sizeof(Times),
  406. NULL
  407. );
  408. if ( !NT_SUCCESS(Status) ) {
  409. ExitProcess((DWORD)Status);
  410. }
  411. }
  412. else {
  413. Status = NtQueryInformationProcess(
  414. ProcessInformation.hProcess,
  415. ProcessTimes,
  416. &Times,
  417. sizeof(Times),
  418. NULL
  419. );
  420. if ( !NT_SUCCESS(Status) ) {
  421. ExitProcess((DWORD)Status);
  422. }
  423. }
  424. if ( bFull ) {
  425. if ( OtherProcess ) {
  426. Status = NtQueryInformationProcess(
  427. OtherProcess,
  428. ProcessVmCounters,
  429. &ServerVmInfoDone,
  430. sizeof(VM_COUNTERS),
  431. NULL
  432. );
  433. if ( !NT_SUCCESS(Status) ) {
  434. ExitProcess((DWORD)Status);
  435. }
  436. }
  437. if ( ProcessHandle ) {
  438. Status = NtQueryInformationProcess(
  439. ProcessHandle,
  440. ProcessVmCounters,
  441. &ProcessVmInfoDone,
  442. sizeof(VM_COUNTERS),
  443. NULL
  444. );
  445. if ( !NT_SUCCESS(Status) ) {
  446. ExitProcess((DWORD)Status);
  447. }
  448. }
  449. else {
  450. Status = NtQueryInformationProcess(
  451. ProcessInformation.hProcess,
  452. ProcessVmCounters,
  453. &ProcessVmInfoDone,
  454. sizeof(VM_COUNTERS),
  455. NULL
  456. );
  457. if ( !NT_SUCCESS(Status) ) {
  458. ExitProcess((DWORD)Status);
  459. }
  460. }
  461. #ifdef i386
  462. Status = NtQuerySystemInformation(
  463. SystemVdmInstemulInformation,
  464. &VdmInfoDone,
  465. sizeof(VdmInfoStart),
  466. NULL
  467. );
  468. if (!NT_SUCCESS(Status)) {
  469. printf("Failed to query vdm information\n");
  470. ExitProcess((DWORD)Status);
  471. }
  472. #endif
  473. Status = NtQuerySystemInformation(SystemProcessorPerformanceInformation,
  474. (PVOID)&ProcessorInfoDone,
  475. sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * MAX_PROCESSOR,
  476. NULL);
  477. if (!NT_SUCCESS(Status)) {
  478. printf("Failed to query preocessor performance information\n");
  479. ExitProcess((DWORD)Status);
  480. }
  481. }
  482. if ( bSyscall ) {
  483. Status = NtQuerySystemInformation(SystemCallCountInformation,
  484. (PVOID)SystemCallBufferDone,
  485. BUFFER_SIZE * sizeof(ULONG),
  486. NULL);
  487. if (!NT_SUCCESS(Status)) {
  488. printf("Failed to query system call performance information: %x\n", Status);
  489. bSyscall = FALSE;
  490. }
  491. }
  492. RunTime.QuadPart = Times.ExitTime.QuadPart - Times.CreateTime.QuadPart;
  493. IdleTime.QuadPart = SystemInfoDone.IdleProcessTime.QuadPart -
  494. SystemInfoStart.IdleProcessTime.QuadPart;
  495. RtlTimeToTimeFields ( (PLARGE_INTEGER)&IdleTime, &Itime);
  496. if ( ProcessHandle ) {
  497. RunTime.QuadPart = ProcessDone.UserTime.QuadPart -
  498. ProcessStart.UserTime.QuadPart;
  499. RtlTimeToTimeFields ( (PLARGE_INTEGER)&RunTime, &Utime);
  500. RunTime.QuadPart = ProcessDone.KernelTime.QuadPart -
  501. ProcessStart.KernelTime.QuadPart;
  502. RtlTimeToTimeFields ( (PLARGE_INTEGER)&RunTime, &Ktime);
  503. if (bOneLine) {
  504. printf("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld",
  505. Utime.Hour,
  506. Utime.Minute,
  507. Utime.Second,
  508. Utime.Milliseconds,
  509. Ktime.Hour,
  510. Ktime.Minute,
  511. Ktime.Second,
  512. Ktime.Milliseconds,
  513. Itime.Hour,
  514. Itime.Minute,
  515. Itime.Second,
  516. Itime.Milliseconds
  517. );
  518. }
  519. else {
  520. printf("ProcessTimes ");
  521. printf("UTime( %3ld:%02ld:%02ld.%03ld ) ",
  522. Utime.Hour,
  523. Utime.Minute,
  524. Utime.Second,
  525. Utime.Milliseconds
  526. );
  527. printf("KTime( %3ld:%02ld:%02ld.%03ld ) ",
  528. Ktime.Hour,
  529. Ktime.Minute,
  530. Ktime.Second,
  531. Ktime.Milliseconds
  532. );
  533. printf("ITime( %3ld:%02ld:%02ld.%03ld )\n",
  534. Itime.Hour,
  535. Itime.Minute,
  536. Itime.Second,
  537. Itime.Milliseconds
  538. );
  539. }
  540. }
  541. else {
  542. RtlTimeToTimeFields((PLARGE_INTEGER) &RunTime, &Etime);
  543. RtlTimeToTimeFields(&Times.UserTime, &Utime);
  544. RtlTimeToTimeFields(&Times.KernelTime, &Ktime);
  545. if (bOneLine) {
  546. printf("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld",
  547. Etime.Hour,
  548. Etime.Minute,
  549. Etime.Second,
  550. Etime.Milliseconds,
  551. Utime.Hour,
  552. Utime.Minute,
  553. Utime.Second,
  554. Utime.Milliseconds,
  555. Ktime.Hour,
  556. Ktime.Minute,
  557. Ktime.Second,
  558. Ktime.Milliseconds,
  559. Itime.Hour,
  560. Itime.Minute,
  561. Itime.Second,
  562. Itime.Milliseconds
  563. );
  564. }
  565. else {
  566. printf("\nETime( %3ld:%02ld:%02ld.%03ld ) ",
  567. Etime.Hour,
  568. Etime.Minute,
  569. Etime.Second,
  570. Etime.Milliseconds
  571. );
  572. printf("UTime( %3ld:%02ld:%02ld.%03ld ) ",
  573. Utime.Hour,
  574. Utime.Minute,
  575. Utime.Second,
  576. Utime.Milliseconds
  577. );
  578. printf("KTime( %3ld:%02ld:%02ld.%03ld )\n",
  579. Ktime.Hour,
  580. Ktime.Minute,
  581. Ktime.Second,
  582. Ktime.Milliseconds
  583. );
  584. printf("ITime( %3ld:%02ld:%02ld.%03ld )\n",
  585. Itime.Hour,
  586. Itime.Minute,
  587. Itime.Second,
  588. Itime.Milliseconds
  589. );
  590. }
  591. }
  592. if ( OtherProcess ) {
  593. RunTime.QuadPart = ServerDone.UserTime.QuadPart -
  594. ServerStart.UserTime.QuadPart;
  595. RtlTimeToTimeFields ( (PLARGE_INTEGER)&RunTime, &Utime);
  596. RunTime.QuadPart = ServerDone.KernelTime.QuadPart -
  597. ServerStart.KernelTime.QuadPart;
  598. RtlTimeToTimeFields ( (PLARGE_INTEGER)&RunTime, &Ktime);
  599. printf("ServerTimes ");
  600. if (bOneLine) {
  601. printf("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld",
  602. Utime.Hour,
  603. Utime.Minute,
  604. Utime.Second,
  605. Utime.Milliseconds,
  606. Ktime.Hour,
  607. Ktime.Minute,
  608. Ktime.Second,
  609. Ktime.Milliseconds,
  610. Itime.Hour,
  611. Itime.Minute,
  612. Itime.Second,
  613. Itime.Milliseconds
  614. );
  615. }
  616. else {
  617. printf("UTime( %3ld:%02ld:%02ld.%03ld ) ",
  618. Utime.Hour,
  619. Utime.Minute,
  620. Utime.Second,
  621. Utime.Milliseconds
  622. );
  623. printf("KTime( %3ld:%02ld:%02ld.%03ld )\n",
  624. Ktime.Hour,
  625. Ktime.Minute,
  626. Ktime.Second,
  627. Ktime.Milliseconds
  628. );
  629. printf("ITime( %3ld:%02ld:%02ld.%03ld )\n",
  630. Itime.Hour,
  631. Itime.Minute,
  632. Itime.Second,
  633. Itime.Milliseconds
  634. );
  635. }
  636. }
  637. if ( bFull ) {
  638. ULONG InterruptCount;
  639. ULONG PreviousInterruptCount;
  640. #ifdef i386
  641. ULONG EmulationTotal;
  642. #endif
  643. PreviousInterruptCount = 0;
  644. for (i=0; i < (ULONG)BasicInfo.NumberOfProcessors; i++) {
  645. PreviousInterruptCount += ProcessorInfoStart[i].InterruptCount;
  646. }
  647. InterruptCount = 0;
  648. for (i=0; i < (ULONG)BasicInfo.NumberOfProcessors; i++) {
  649. InterruptCount += ProcessorInfoDone[i].InterruptCount;
  650. }
  651. if (bOneLine) {
  652. printf(" %ld",ProcessVmInfoDone.PageFaultCount - ProcessVmInfoStart.PageFaultCount);
  653. if (OtherProcess) {
  654. printf(" %ld",ServerVmInfoDone.PageFaultCount - ServerVmInfoStart.PageFaultCount);
  655. }
  656. printf(" %ld", InterruptCount - PreviousInterruptCount);
  657. printf(" %ld", SystemInfoDone.ContextSwitches - SystemInfoStart.ContextSwitches);
  658. printf(" %ld", SystemInfoDone.SystemCalls - SystemInfoStart.SystemCalls);
  659. }
  660. else {
  661. printf("\n");
  662. printf("Process PageFaultCount %ld\n",ProcessVmInfoDone.PageFaultCount - ProcessVmInfoStart.PageFaultCount);
  663. if (OtherProcess) {
  664. printf("Server PageFaultCount %ld\n",ServerVmInfoDone.PageFaultCount - ServerVmInfoStart.PageFaultCount);
  665. }
  666. printf("Total Interrupts %ld\n", InterruptCount - PreviousInterruptCount);
  667. printf("Total Context Switches %ld\n", SystemInfoDone.ContextSwitches - SystemInfoStart.ContextSwitches);
  668. printf("Total System Calls %ld\n", SystemInfoDone.SystemCalls - SystemInfoStart.SystemCalls);
  669. }
  670. if (ProcessHandle) {
  671. #ifdef i386
  672. printf("\n");
  673. printf("Total OpcodeHLT %ld\n", vdelta(OpcodeHLT ));
  674. printf("Total OpcodeCLI %ld\n", vdelta(OpcodeCLI ));
  675. printf("Total OpcodeSTI %ld\n", vdelta(OpcodeSTI ));
  676. printf("Total BopCount %ld\n", vdelta(BopCount ));
  677. printf("Total SegmentNotPresent %ld\n", vdelta(SegmentNotPresent ));
  678. printf("Total OpcodePUSHF %ld\n", vdelta(OpcodePUSHF ));
  679. printf("Total OpcodePOPF %ld\n", vdelta(OpcodePOPF ));
  680. printf("Total VdmOpcode0F %ld\n", vdelta(VdmOpcode0F ));
  681. printf("Total OpcodeINSB %ld\n", vdelta(OpcodeINSB ));
  682. printf("Total OpcodeINSW %ld\n", vdelta(OpcodeINSW ));
  683. printf("Total OpcodeOUTSB %ld\n", vdelta(OpcodeOUTSB ));
  684. printf("Total OpcodeOUTSW %ld\n", vdelta(OpcodeOUTSW ));
  685. printf("Total OpcodeINTnn %ld\n", vdelta(OpcodeINTnn ));
  686. printf("Total OpcodeINTO %ld\n", vdelta(OpcodeINTO ));
  687. printf("Total OpcodeIRET %ld\n", vdelta(OpcodeIRET ));
  688. printf("Total OpcodeINBimm %ld\n", vdelta(OpcodeINBimm ));
  689. printf("Total OpcodeINWimm %ld\n", vdelta(OpcodeINWimm ));
  690. printf("Total OpcodeOUTBimm %ld\n", vdelta(OpcodeOUTBimm ));
  691. printf("Total OpcodeOUTWimm %ld\n", vdelta(OpcodeOUTWimm ));
  692. printf("Total OpcodeINB %ld\n", vdelta(OpcodeINB ));
  693. printf("Total OpcodeINW %ld\n", vdelta(OpcodeINW ));
  694. printf("Total OpcodeOUTB %ld\n", vdelta(OpcodeOUTB ));
  695. printf("Total OpcodeOUTW %ld\n", vdelta(OpcodeOUTW ));
  696. EmulationTotal = vdelta(OpcodeHLT )+
  697. vdelta(OpcodeCLI )+
  698. vdelta(OpcodeSTI )+
  699. vdelta(BopCount )+
  700. vdelta(SegmentNotPresent )+
  701. vdelta(OpcodePUSHF )+
  702. vdelta(OpcodePOPF )+
  703. vdelta(VdmOpcode0F )+
  704. vdelta(OpcodeINSB )+
  705. vdelta(OpcodeINSW )+
  706. vdelta(OpcodeOUTSB )+
  707. vdelta(OpcodeOUTSW )+
  708. vdelta(OpcodeINTnn )+
  709. vdelta(OpcodeINTO )+
  710. vdelta(OpcodeIRET )+
  711. vdelta(OpcodeINBimm )+
  712. vdelta(OpcodeINWimm )+
  713. vdelta(OpcodeOUTBimm )+
  714. vdelta(OpcodeOUTWimm )+
  715. vdelta(OpcodeINB )+
  716. vdelta(OpcodeINW )+
  717. vdelta(OpcodeOUTB )+
  718. vdelta(OpcodeOUTW )
  719. ;
  720. if (bOneLine) {
  721. printf(" %ld %ld", EmulationTotal, EmulationTotal*515);
  722. }
  723. else {
  724. printf("\n");
  725. printf("Total Emulation %ld * 515clocks = %ld cycles\n", EmulationTotal, EmulationTotal*515);
  726. }
  727. #endif
  728. }
  729. if (bSyscall) {
  730. for (i = 0; i < NumberOfCounts; i += 1) {
  731. CallData[i] = SystemCallTableDone[i] - SystemCallTableStart[i];
  732. }
  733. SortUlongData(NumberOfCounts, Index, CallData);
  734. for (i = 0; i < NumberOfCounts; i += 1) {
  735. if (CallData[Index[i]] == 0) {
  736. break;
  737. }
  738. printf("%8ld calls to %s\n", CallData[Index[i]], CallTable[Index[i]]);
  739. }
  740. }
  741. if (bOneLine) {
  742. printf("\n");
  743. }
  744. } else {
  745. printf("\n");
  746. }
  747. return 0;
  748. }