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.

399 lines
11 KiB

  1. //
  2. // Systrack - System resource tracking
  3. // Copyright (c) Microsoft Corporation, 1997
  4. //
  5. //
  6. // module: process.cxx
  7. // author: silviuc
  8. // created: Mon Nov 09 16:03:42 1998
  9. //
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <stdarg.h>
  13. #include <time.h>
  14. extern "C" {
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. }
  19. #include <windows.h>
  20. #include "assert.hxx"
  21. #include "history.hxx"
  22. #include "table.hxx"
  23. #include "systrack.hxx"
  24. //////////////////////////////////////////////////////////////////////
  25. //////////////////////////////////////////////////////////////////////
  26. //////////////////////////////////////////////////////////////////////
  27. #define TRACK_PROCESS_TABLE_SIZE 256
  28. #define TRACK_PROCESS_HISTORY_SIZE 60
  29. //////////////////////////////////////////////////////////////////////
  30. //////////////////////////////////////////////////////////////////////
  31. //////////////////////////////////////////////////////////////////////
  32. class TRACK_PROCESS_INFORMATION
  33. {
  34. public:
  35. union {
  36. ULONG Key;
  37. ULONG Id;
  38. };
  39. History<SIZE_T, TRACK_PROCESS_HISTORY_SIZE> Threads;
  40. History<SIZE_T, TRACK_PROCESS_HISTORY_SIZE> Handles;
  41. History<SIZE_T, TRACK_PROCESS_HISTORY_SIZE> WorkingSetSize;
  42. History<SIZE_T, TRACK_PROCESS_HISTORY_SIZE> VirtualSize;
  43. History<SIZE_T, TRACK_PROCESS_HISTORY_SIZE> PagefileUsage;
  44. public:
  45. bool VerifyThreads (SIZE_T DeltaValue) {
  46. return Threads.Delta (DeltaValue);
  47. }
  48. bool VerifyHandles (SIZE_T DeltaValue) {
  49. return Handles.Delta (DeltaValue);
  50. }
  51. bool VerifyWorkingSetSize (SIZE_T DeltaValue) {
  52. return WorkingSetSize.Delta (DeltaValue);
  53. }
  54. bool VerifyVirtualSize (SIZE_T DeltaValue) {
  55. return VirtualSize.Delta (DeltaValue);
  56. }
  57. bool VerifyPagefileUsage (SIZE_T DeltaValue) {
  58. return PagefileUsage.Delta (DeltaValue);
  59. }
  60. void Print (UNICODE_STRING Name) {
  61. static unsigned Calls = 0;
  62. if (Calls % 25 == 0)
  63. {
  64. printf (" - - - - - - - - - - - - - - - - - - - -");
  65. printf (" - - - - - - - - - - - - - - - - - - - - \n");
  66. printf ("%-15s %-5s %-13s %-11s %-11s %-11s %-11s \n",
  67. "Process", "Id", "Handles", "Threads",
  68. "WSet(Mb)", "Vsize(Mb)", "Pfile(Mb)");
  69. printf (" - - - - - - - - - - - - - - - - - - - -");
  70. printf (" - - - - - - - - - - - - - - - - - - - - \n");
  71. fflush( stdout );
  72. }
  73. Calls++;
  74. printf ("%-15ws %-5u ", Name.Buffer, Key);
  75. printf ("%-6u %-6u %-5u %-5u %-5u %-5u %-5u %-5u %-5u %-5u\n",
  76. Handles.Last(),
  77. Handles.First(),
  78. Threads.Last(),
  79. Threads.First(),
  80. WorkingSetSize.Last() / 0x100000,
  81. WorkingSetSize.First() / 0x100000,
  82. VirtualSize.Last() / 0x100000,
  83. VirtualSize.First() / 0x100000,
  84. PagefileUsage.Last() / 0x100000,
  85. PagefileUsage.First() / 0x100000);
  86. fflush( stdout );
  87. DebugMessage ("systrack: %ws (%u): Hndl: %u +%d, Thrd: %u +%d, "
  88. "Wset: %u +%d, Vsize: %u +%d, Pfile: %u +%d\n",
  89. Name.Buffer,
  90. Key,
  91. Handles.Last(),
  92. Handles.Last() - Handles.First(),
  93. Threads.Last(),
  94. Threads.Last() - Threads.First(),
  95. WorkingSetSize.Last() / 0x100000,
  96. ( (int)WorkingSetSize.Last() - (int)WorkingSetSize.First()) / 0x100000,
  97. VirtualSize.Last() / 0x100000,
  98. ( (int)VirtualSize.Last() - (int)VirtualSize.First()) / 0x100000,
  99. PagefileUsage.Last() / 0x100000,
  100. ( (int)PagefileUsage.Last() - (int)PagefileUsage.First()) / 0x100000);
  101. }
  102. };
  103. typedef TRACK_PROCESS_INFORMATION * PTRACK_PROCESS_INFORMATION;
  104. //////////////////////////////////////////////////////////////////////
  105. //////////////////////////////////////////////////////////////////////
  106. //////////////////////////////////////////////////////////////////////
  107. Table<TRACK_PROCESS_INFORMATION, TRACK_PROCESS_TABLE_SIZE> ProcessTable;
  108. //////////////////////////////////////////////////////////////////////
  109. //////////////////////////////////////////////////////////////////////
  110. //////////////////////////////////////////////////////////////////////
  111. void
  112. SystemProcessTrack (
  113. ULONG Period,
  114. ULONG DeltaHandles,
  115. ULONG DeltaThreads,
  116. ULONG DeltaWorkingSetSize,
  117. SIZE_T DeltaVirtualSize,
  118. SIZE_T DeltaPagefileUsage)
  119. {
  120. NTSTATUS Status;
  121. ULONG RealLength;
  122. PSYSTEM_PROCESS_INFORMATION Info;
  123. BOOL FinishNextTime = FALSE;
  124. BOOL PrintThreads, PrintHandles, PrintWSSize, PrintVirtSize, PrintPageFile;
  125. for ( ; ; )
  126. {
  127. //
  128. // SystemPoolTagInformation
  129. //
  130. Info = (PSYSTEM_PROCESS_INFORMATION)QuerySystemProcessInformation();
  131. //
  132. // Loop over the processes and see if something changed.
  133. //
  134. for (FinishNextTime = FALSE;
  135. FinishNextTime == FALSE;
  136. Info = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)Info + Info->NextEntryOffset)) {
  137. PTRACK_PROCESS_INFORMATION Process;
  138. if (Info->NextEntryOffset == 0)
  139. FinishNextTime = TRUE;
  140. //
  141. // Skip over the idle process.
  142. //
  143. if (Info->UniqueProcessId == 0)
  144. continue;
  145. //
  146. // Add process to the process table.
  147. //
  148. Process = ProcessTable.Add (PtrToUlong(Info->UniqueProcessId));
  149. assert_ (Process != 0);
  150. Process->Threads.Add (Info->NumberOfThreads);
  151. Process->Handles.Add (Info->HandleCount);
  152. Process->WorkingSetSize.Add (Info->WorkingSetSize);
  153. Process->VirtualSize.Add (Info->VirtualSize);
  154. Process->PagefileUsage.Add (Info->PagefileUsage);
  155. PrintThreads = FALSE;
  156. if (Process->VerifyThreads (DeltaThreads)) {
  157. PrintThreads = TRUE;
  158. }
  159. PrintHandles = FALSE;
  160. if (Process->VerifyHandles (DeltaHandles)) {
  161. PrintHandles = TRUE;
  162. }
  163. PrintWSSize = FALSE;
  164. if (Process->VerifyWorkingSetSize (DeltaWorkingSetSize)) {
  165. PrintWSSize = TRUE;
  166. }
  167. PrintVirtSize = FALSE;
  168. if (Process->VerifyVirtualSize (DeltaVirtualSize)) {
  169. PrintVirtSize = TRUE;
  170. }
  171. PrintPageFile = FALSE;
  172. if (Process->VerifyPagefileUsage (DeltaPagefileUsage)) {
  173. PrintPageFile = TRUE;
  174. }
  175. if( PrintThreads || PrintHandles || PrintWSSize || PrintVirtSize || PrintPageFile ) {
  176. Process->Print(Info->ImageName);
  177. if( PrintThreads ) {
  178. Process->Threads.Reset (Info->NumberOfThreads);
  179. }
  180. if( PrintHandles ) {
  181. Process->Handles.Reset (Info->HandleCount);
  182. }
  183. if( PrintWSSize ) {
  184. Process->WorkingSetSize.Reset (Info->WorkingSetSize);
  185. }
  186. if( PrintVirtSize ) {
  187. Process->VirtualSize.Reset (Info->VirtualSize);
  188. }
  189. if( PrintPageFile ) {
  190. Process->PagefileUsage.Reset (Info->PagefileUsage);
  191. }
  192. }
  193. }
  194. //
  195. // Sleep a little bit.
  196. //
  197. Sleep (Period);
  198. }
  199. }
  200. void
  201. SystemProcessIdTrack (
  202. ULONG Period,
  203. ULONG ProcessId,
  204. ULONG DeltaHandles,
  205. ULONG DeltaThreads,
  206. ULONG DeltaWorkingSetSize,
  207. SIZE_T DeltaVirtualSize,
  208. SIZE_T DeltaPagefileUsage)
  209. {
  210. NTSTATUS Status;
  211. ULONG RealLength;
  212. PSYSTEM_PROCESS_INFORMATION Info;
  213. BOOL FinishNextTime = FALSE;
  214. BOOL PrintThreads, PrintHandles, PrintWSSize, PrintVirtSize, PrintPageFile;
  215. for ( ; ; )
  216. {
  217. //
  218. // SystemProcessInformation
  219. //
  220. Info = (PSYSTEM_PROCESS_INFORMATION)QuerySystemProcessInformation();
  221. //
  222. // Loop over the processes and see if something changed.
  223. //
  224. for (FinishNextTime = FALSE;
  225. FinishNextTime == FALSE;
  226. Info = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)Info + Info->NextEntryOffset)) {
  227. PTRACK_PROCESS_INFORMATION Process;
  228. if (Info->NextEntryOffset == 0)
  229. FinishNextTime = TRUE;
  230. //
  231. // Skip over the idle process.
  232. //
  233. if (Info->UniqueProcessId == 0)
  234. continue;
  235. //
  236. // If this is not the process we want to track
  237. // skip it.
  238. //
  239. if ((ULONG_PTR)(Info->UniqueProcessId) != ProcessId)
  240. continue;
  241. //
  242. // Add process to the process table.
  243. //
  244. Process = ProcessTable.Add (PtrToUlong(Info->UniqueProcessId));
  245. assert_ (Process != 0);
  246. Process->Threads.Add (Info->NumberOfThreads);
  247. Process->Handles.Add (Info->HandleCount);
  248. Process->WorkingSetSize.Add (Info->WorkingSetSize);
  249. Process->VirtualSize.Add (Info->VirtualSize);
  250. Process->PagefileUsage.Add (Info->PagefileUsage);
  251. PrintThreads = FALSE;
  252. if (Process->VerifyThreads (DeltaThreads)) {
  253. PrintThreads = TRUE;
  254. }
  255. PrintHandles = FALSE;
  256. if (Process->VerifyHandles (DeltaHandles)) {
  257. PrintHandles = TRUE;
  258. }
  259. PrintWSSize = FALSE;
  260. if (Process->VerifyWorkingSetSize (DeltaWorkingSetSize)) {
  261. PrintWSSize = TRUE;
  262. }
  263. PrintVirtSize = FALSE;
  264. if (Process->VerifyVirtualSize (DeltaVirtualSize)) {
  265. PrintVirtSize = TRUE;
  266. }
  267. PrintPageFile = FALSE;
  268. if (Process->VerifyPagefileUsage (DeltaPagefileUsage)) {
  269. PrintPageFile = TRUE;
  270. }
  271. if( PrintThreads || PrintHandles || PrintWSSize || PrintVirtSize || PrintPageFile ) {
  272. Process->Print(Info->ImageName);
  273. if( PrintThreads ) {
  274. Process->Threads.Reset (Info->NumberOfThreads);
  275. }
  276. if( PrintHandles ) {
  277. Process->Handles.Reset (Info->HandleCount);
  278. }
  279. if( PrintWSSize ) {
  280. Process->WorkingSetSize.Reset (Info->WorkingSetSize);
  281. }
  282. if( PrintVirtSize ) {
  283. Process->VirtualSize.Reset (Info->VirtualSize);
  284. }
  285. if( PrintPageFile ) {
  286. Process->PagefileUsage.Reset (Info->PagefileUsage);
  287. }
  288. }
  289. }
  290. //
  291. // Sleep a little bit.
  292. //
  293. Sleep (Period);
  294. }
  295. }
  296. //
  297. // end of module: process.cxx
  298. //