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.

215 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. perfmem.c
  5. Abstract:
  6. This file implements an Performance Object that presents
  7. System Memory Performance Object
  8. Created:
  9. Bob Watson 22-Oct-1996
  10. Revision History
  11. --*/
  12. //
  13. // Include Files
  14. //
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <ntmmapi.h>
  19. #include <windows.h>
  20. #include <winperf.h>
  21. #include <ntprfctr.h>
  22. #include <perfutil.h>
  23. #include "perfos.h"
  24. #include "perfosmc.h"
  25. #include "datamem.h"
  26. static DWORD dwOpenCount = 0; // count of "Open" threads
  27. DWORD APIENTRY
  28. CollectMemoryObjectData (
  29. IN OUT LPVOID *lppData,
  30. IN OUT LPDWORD lpcbTotalBytes,
  31. IN OUT LPDWORD lpNumObjectTypes
  32. )
  33. /*++
  34. Routine Description:
  35. This routine will return the data for the XXX object
  36. Arguments:
  37. IN OUT LPVOID *lppData
  38. IN: pointer to the address of the buffer to receive the completed
  39. PerfDataBlock and subordinate structures. This routine will
  40. append its data to the buffer starting at the point referenced
  41. by *lppData.
  42. OUT: points to the first byte after the data structure added by this
  43. routine. This routine updated the value at lppdata after appending
  44. its data.
  45. IN OUT LPDWORD lpcbTotalBytes
  46. IN: the address of the DWORD that tells the size in bytes of the
  47. buffer referenced by the lppData argument
  48. OUT: the number of bytes added by this routine is writted to the
  49. DWORD pointed to by this argument
  50. IN OUT LPDWORD NumObjectTypes
  51. IN: the address of the DWORD to receive the number of objects added
  52. by this routine
  53. OUT: the number of objects added by this routine is writted to the
  54. DWORD pointed to by this argument
  55. Returns:
  56. 0 if successful, else Win 32 error code of failure
  57. --*/
  58. {
  59. NTSTATUS Status;
  60. DWORD TotalLen; // Length of the total return block
  61. PMEMORY_DATA_DEFINITION pMemoryDataDefinition;
  62. SYSTEM_FILECACHE_INFORMATION FileCache;
  63. PMEMORY_COUNTER_DATA pMCD;
  64. DWORD LocalPageSize;
  65. pMemoryDataDefinition = (MEMORY_DATA_DEFINITION *) *lppData;
  66. //
  67. // Check for enough space for memory data block
  68. //
  69. TotalLen = sizeof(MEMORY_DATA_DEFINITION) +
  70. sizeof(MEMORY_COUNTER_DATA);
  71. TotalLen = QWORD_MULTIPLE (TotalLen);
  72. if ( *lpcbTotalBytes < TotalLen ) {
  73. *lpcbTotalBytes = (DWORD) 0;
  74. *lpNumObjectTypes = (DWORD) 0;
  75. return ERROR_MORE_DATA;
  76. }
  77. Status = NtQuerySystemInformation(
  78. SystemFileCacheInformation,
  79. &FileCache,
  80. sizeof(FileCache),
  81. NULL
  82. );
  83. if (!NT_SUCCESS(Status)) {
  84. ReportEvent (hEventLog,
  85. EVENTLOG_WARNING_TYPE,
  86. 0,
  87. PERFOS_UNABLE_QUERY_FILE_CACHE_INFO,
  88. NULL,
  89. 0,
  90. sizeof(DWORD),
  91. NULL,
  92. (LPVOID)&Status);
  93. memset (&FileCache, 0, sizeof(FileCache));
  94. }
  95. //
  96. // Define memory data block
  97. //
  98. memcpy (pMemoryDataDefinition,
  99. &MemoryDataDefinition,
  100. sizeof(MEMORY_DATA_DEFINITION));
  101. //
  102. // Format and collect memory data
  103. //
  104. LocalPageSize = BasicInfo.PageSize;
  105. pMCD = (PMEMORY_COUNTER_DATA)&pMemoryDataDefinition[1];
  106. pMCD->CounterBlock.ByteLength = sizeof (MEMORY_COUNTER_DATA);
  107. pMCD->AvailablePages = SysPerfInfo.AvailablePages;
  108. pMCD->AvailablePages *= LocalPageSize; // display as bytes
  109. pMCD->AvailableKBytes = pMCD->AvailablePages / 1024;
  110. pMCD->AvailableMBytes = pMCD->AvailableKBytes / 1024;
  111. pMCD->CommittedPages = SysPerfInfo.CommittedPages;
  112. pMCD->CommittedPages *= LocalPageSize;
  113. pMCD->CommitList = SysPerfInfo.CommitLimit;
  114. pMCD->CommitList *= LocalPageSize;
  115. pMCD->PageFaults = SysPerfInfo.PageFaultCount;
  116. pMCD->WriteCopies = SysPerfInfo.CopyOnWriteCount;
  117. pMCD->TransitionFaults = SysPerfInfo.TransitionCount;
  118. pMCD->CacheFaults = FileCache.PageFaultCount;
  119. pMCD->DemandZeroFaults = SysPerfInfo.DemandZeroCount;
  120. pMCD->Pages = SysPerfInfo.PageReadCount +
  121. SysPerfInfo.DirtyPagesWriteCount;
  122. pMCD->PagesInput = SysPerfInfo.PageReadCount;
  123. pMCD->PageReads = SysPerfInfo.PageReadIoCount;
  124. pMCD->DirtyPages = SysPerfInfo.DirtyPagesWriteCount;
  125. pMCD->DirtyWrites = SysPerfInfo.DirtyWriteIoCount;
  126. pMCD->PagedPool = SysPerfInfo.PagedPoolPages;
  127. pMCD->PagedPool *= LocalPageSize;
  128. pMCD->NonPagedPool = SysPerfInfo.NonPagedPoolPages;
  129. pMCD->NonPagedPool *= LocalPageSize;
  130. pMCD->PagedPoolAllocs = SysPerfInfo.PagedPoolAllocs -
  131. SysPerfInfo.PagedPoolFrees;
  132. pMCD->NonPagedPoolAllocs = SysPerfInfo.NonPagedPoolAllocs -
  133. SysPerfInfo.NonPagedPoolFrees;
  134. pMCD->FreeSystemPtes = SysPerfInfo.FreeSystemPtes;
  135. pMCD->CacheBytes = FileCache.CurrentSize;
  136. pMCD->PeakCacheBytes = FileCache.PeakSize;
  137. pMCD->ResidentPagedPoolBytes = SysPerfInfo.ResidentPagedPoolPage;
  138. pMCD->ResidentPagedPoolBytes *= LocalPageSize;
  139. pMCD->TotalSysCodeBytes = SysPerfInfo.TotalSystemCodePages;
  140. pMCD->TotalSysCodeBytes *= LocalPageSize;
  141. pMCD->ResidentSysCodeBytes = SysPerfInfo.ResidentSystemCodePage;
  142. pMCD->ResidentSysCodeBytes *= LocalPageSize;
  143. pMCD->TotalSysDriverBytes = SysPerfInfo.TotalSystemDriverPages;
  144. pMCD->TotalSysDriverBytes *= LocalPageSize;
  145. pMCD->ResidentSysDriverBytes = SysPerfInfo.ResidentSystemDriverPage;
  146. pMCD->ResidentSysDriverBytes *= LocalPageSize;
  147. pMCD->ResidentSysCacheBytes = SysPerfInfo.ResidentSystemCachePage;
  148. pMCD->ResidentSysCacheBytes *= LocalPageSize;
  149. // This is reported as a percentage of CommittedPages/CommitLimit.
  150. // these value return a value in "page" units. Since this is a
  151. // fraction, the page size (i.e. converting pages to bytes) will
  152. // cancel out and as such can be ignored, saving some CPU cycles
  153. //
  154. pMCD->CommitBytesInUse = SysPerfInfo.CommittedPages;
  155. pMCD->CommitBytesLimit = SysPerfInfo.CommitLimit;
  156. #if 0 // no longer supported
  157. // load the VLM counters - this should really be removed period.
  158. pMCD->SystemVlmCommitCharge = 0;
  159. pMCD->SystemVlmPeakCommitCharge = 0;
  160. pMCD->SystemVlmSharedCommitCharge = 0;
  161. #endif
  162. *lppData = (LPVOID)&pMCD[1];
  163. // round up buffer to the nearest QUAD WORD
  164. *lppData = ALIGN_ON_QWORD (*lppData);
  165. *lpcbTotalBytes =
  166. pMemoryDataDefinition->MemoryObjectType.TotalByteLength =
  167. (DWORD)((LPBYTE)*lppData - (LPBYTE)pMemoryDataDefinition);
  168. *lpNumObjectTypes = 1;
  169. return ERROR_SUCCESS;
  170. }