mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / programs / taskmgr / perfdata.c
blob2cbd6b01669168e3b6761ade75fcbc3e850366f8
1 /*
2 * ReactOS Task Manager
4 * perfdata.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdio.h>
24 #include <stdlib.h>
26 #include <windows.h>
27 #include <commctrl.h>
28 #include <winnt.h>
30 #include "taskmgr.h"
31 #include "perfdata.h"
33 static CRITICAL_SECTION PerfDataCriticalSection;
34 static PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */
35 static PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */
36 static ULONG ProcessCountOld = 0;
37 static ULONG ProcessCount = 0;
38 static double dbIdleTime;
39 static double dbKernelTime;
40 static double dbSystemTime;
41 static LARGE_INTEGER liOldIdleTime = {{0,0}};
42 static double OldKernelTime = 0;
43 static LARGE_INTEGER liOldSystemTime = {{0,0}};
44 static SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
45 static SYSTEM_BASIC_INFORMATION SystemBasicInfo;
46 static SYSTEM_CACHE_INFORMATION SystemCacheInfo;
47 static SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
48 static PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
50 static size_t size_diff(size_t x, size_t y)
52 return x > y ? x - y : y - x;
55 BOOL PerfDataInitialize(void)
57 LONG status;
59 InitializeCriticalSection(&PerfDataCriticalSection);
62 * Get number of processors in the system
64 status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
65 if (status != NO_ERROR)
66 return FALSE;
68 return TRUE;
71 void PerfDataRefresh(void)
73 ULONG ulSize;
74 LONG status;
75 LPBYTE pBuffer;
76 ULONG BufferSize;
77 PSYSTEM_PROCESS_INFORMATION pSPI;
78 PPERFDATA pPDOld;
79 ULONG Idx, Idx2;
80 HANDLE hProcess;
81 HANDLE hProcessToken;
82 WCHAR wszTemp[MAX_PATH];
83 DWORD dwSize;
84 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
85 SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo;
86 SYSTEM_CACHE_INFORMATION SysCacheInfo;
87 LPBYTE SysHandleInfoData;
88 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *SysProcessorTimeInfo;
89 double CurrentKernelTime;
92 /* Get new system time */
93 status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
94 if (status != NO_ERROR)
95 return;
97 /* Get new CPU's idle time */
98 status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
99 if (status != NO_ERROR)
100 return;
102 /* Get system cache information */
103 status = NtQuerySystemInformation(SystemFileCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
104 if (status != NO_ERROR)
105 return;
107 /* Get processor time information */
108 SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0,
109 sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors);
110 status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo,
111 sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors, &ulSize);
112 if (status != NO_ERROR) {
113 HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo);
114 return;
117 /* Get handle information
118 * We don't know how much data there is so just keep
119 * increasing the buffer size until the call succeeds
121 BufferSize = 0;
124 BufferSize += 0x10000;
125 SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize);
127 status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
129 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
130 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
133 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
135 /* Get process information
136 * We don't know how much data there is so just keep
137 * increasing the buffer size until the call succeeds
139 BufferSize = 0;
142 BufferSize += 0x10000;
143 pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
145 status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
147 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
148 HeapFree(GetProcessHeap(), 0, pBuffer);
151 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
153 EnterCriticalSection(&PerfDataCriticalSection);
156 * Save system performance info
158 memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
161 * Save system cache info
163 memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
166 * Save system processor time info
168 HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
169 SystemProcessorTimeInfo = SysProcessorTimeInfo;
172 * Save system handle info
174 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
175 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
177 for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) {
178 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
179 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[0]);
180 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[1]);
183 /* If it's a first call - skip idle time calcs */
184 if (liOldIdleTime.QuadPart != 0) {
185 /* CurrentValue = NewValue - OldValue */
186 dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
187 dbKernelTime = CurrentKernelTime - OldKernelTime;
188 dbSystemTime = Li2Double(SysTimeInfo.SystemTime) - Li2Double(liOldSystemTime);
190 /* CurrentCpuIdle = IdleTime / SystemTime */
191 dbIdleTime = dbIdleTime / dbSystemTime;
192 dbKernelTime = dbKernelTime / dbSystemTime;
194 /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
195 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
196 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
199 /* Store new CPU's idle and system time */
200 liOldIdleTime = SysPerfInfo.IdleTime;
201 liOldSystemTime = SysTimeInfo.SystemTime;
202 OldKernelTime = CurrentKernelTime;
204 /* Determine the process count
205 * We loop through the data we got from NtQuerySystemInformation
206 * and count how many structures there are (until RelativeOffset is 0)
208 ProcessCountOld = ProcessCount;
209 ProcessCount = 0;
210 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
211 while (pSPI) {
212 ProcessCount++;
213 if (pSPI->NextEntryOffset == 0)
214 break;
215 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
218 /* Now alloc a new PERFDATA array and fill in the data */
219 HeapFree(GetProcessHeap(), 0, pPerfDataOld);
220 pPerfDataOld = pPerfData;
221 pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount);
222 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
223 for (Idx=0; Idx<ProcessCount; Idx++) {
224 /* Get the old perf data for this process (if any) */
225 /* so that we can establish delta values */
226 pPDOld = NULL;
227 for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
228 if (pPerfDataOld[Idx2].ProcessId == (DWORD_PTR)pSPI->UniqueProcessId) {
229 pPDOld = &pPerfDataOld[Idx2];
230 break;
234 /* Clear out process perf data structure */
235 memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
237 if (pSPI->ProcessName.Buffer)
238 lstrcpyW(pPerfData[Idx].ImageName, pSPI->ProcessName.Buffer);
239 else
241 WCHAR idleW[255];
242 LoadStringW(hInst, IDS_SYSTEM_IDLE_PROCESS, idleW, ARRAY_SIZE(idleW));
243 lstrcpyW(pPerfData[Idx].ImageName, idleW );
246 pPerfData[Idx].ProcessId = (DWORD_PTR)pSPI->UniqueProcessId;
248 if (pPDOld) {
249 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
250 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
251 double CpuTime = (CurTime - OldTime) / dbSystemTime;
252 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
253 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
256 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
257 pPerfData[Idx].vmCounters.WorkingSetSize = pSPI->vmCounters.WorkingSetSize;
258 pPerfData[Idx].vmCounters.PeakWorkingSetSize = pSPI->vmCounters.PeakWorkingSetSize;
259 if (pPDOld)
260 pPerfData[Idx].WorkingSetSizeDelta = size_diff(pSPI->vmCounters.WorkingSetSize, pPDOld->vmCounters.WorkingSetSize);
261 else
262 pPerfData[Idx].WorkingSetSizeDelta = 0;
263 pPerfData[Idx].vmCounters.PageFaultCount = pSPI->vmCounters.PageFaultCount;
264 if (pPDOld)
265 pPerfData[Idx].PageFaultCountDelta = size_diff(pSPI->vmCounters.PageFaultCount, pPDOld->vmCounters.PageFaultCount);
266 else
267 pPerfData[Idx].PageFaultCountDelta = 0;
268 pPerfData[Idx].vmCounters.VirtualSize = pSPI->vmCounters.VirtualSize;
269 pPerfData[Idx].vmCounters.QuotaPagedPoolUsage = pSPI->vmCounters.QuotaPagedPoolUsage;
270 pPerfData[Idx].vmCounters.QuotaNonPagedPoolUsage = pSPI->vmCounters.QuotaNonPagedPoolUsage;
271 pPerfData[Idx].BasePriority = pSPI->dwBasePriority;
272 pPerfData[Idx].HandleCount = pSPI->HandleCount;
273 pPerfData[Idx].ThreadCount = pSPI->dwThreadCount;
274 pPerfData[Idx].SessionId = pSPI->SessionId;
276 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD_PTR)pSPI->UniqueProcessId);
277 if (hProcess) {
278 if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
279 ImpersonateLoggedOnUser(hProcessToken);
280 memset(wszTemp, 0, sizeof(wszTemp));
281 dwSize = MAX_PATH;
282 GetUserNameW(wszTemp, &dwSize);
283 RevertToSelf();
284 CloseHandle(hProcessToken);
286 pPerfData[Idx].USERObjectCount = GetGuiResources(hProcess, GR_USEROBJECTS);
287 pPerfData[Idx].GDIObjectCount = GetGuiResources(hProcess, GR_GDIOBJECTS);
288 GetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
289 IsWow64Process(hProcess, &pPerfData[Idx].Wow64Process);
290 CloseHandle(hProcess);
292 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
293 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
294 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
296 HeapFree(GetProcessHeap(), 0, pBuffer);
297 LeaveCriticalSection(&PerfDataCriticalSection);
300 ULONG PerfDataGetProcessCount(void)
302 return ProcessCount;
305 ULONG PerfDataGetProcessorUsage(void)
307 if( dbIdleTime < 0.0 )
308 return 0;
309 if( dbIdleTime > 100.0 )
310 return 100;
311 return (ULONG)dbIdleTime;
314 ULONG PerfDataGetProcessorSystemUsage(void)
316 if( dbKernelTime < 0.0 )
317 return 0;
318 if( dbKernelTime > 100.0 )
319 return 100;
320 return (ULONG)dbKernelTime;
323 BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
325 static const WCHAR proc32W[] = {' ','*','3','2',0};
326 BOOL bSuccessful;
328 EnterCriticalSection(&PerfDataCriticalSection);
330 if (Index < ProcessCount) {
331 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
332 if (pPerfData[Index].Wow64Process &&
333 nMaxCount - lstrlenW(lpImageName) > 4 /* =lstrlenW(proc32W) */)
334 lstrcatW(lpImageName, proc32W);
335 bSuccessful = TRUE;
336 } else {
337 bSuccessful = FALSE;
339 LeaveCriticalSection(&PerfDataCriticalSection);
340 return bSuccessful;
343 ULONG PerfDataGetProcessId(ULONG Index)
345 ULONG ProcessId;
347 EnterCriticalSection(&PerfDataCriticalSection);
349 if (Index < ProcessCount)
350 ProcessId = pPerfData[Index].ProcessId;
351 else
352 ProcessId = 0;
354 LeaveCriticalSection(&PerfDataCriticalSection);
356 return ProcessId;
359 BOOL PerfDataGetUserName(ULONG Index, LPWSTR lpUserName, int nMaxCount)
361 BOOL bSuccessful;
363 EnterCriticalSection(&PerfDataCriticalSection);
365 if (Index < ProcessCount) {
366 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
367 bSuccessful = TRUE;
368 } else {
369 bSuccessful = FALSE;
372 LeaveCriticalSection(&PerfDataCriticalSection);
374 return bSuccessful;
377 ULONG PerfDataGetSessionId(ULONG Index)
379 ULONG SessionId;
381 EnterCriticalSection(&PerfDataCriticalSection);
383 if (Index < ProcessCount)
384 SessionId = pPerfData[Index].SessionId;
385 else
386 SessionId = 0;
388 LeaveCriticalSection(&PerfDataCriticalSection);
390 return SessionId;
393 ULONG PerfDataGetCPUUsage(ULONG Index)
395 ULONG CpuUsage;
397 EnterCriticalSection(&PerfDataCriticalSection);
399 if (Index < ProcessCount)
400 CpuUsage = pPerfData[Index].CPUUsage;
401 else
402 CpuUsage = 0;
404 LeaveCriticalSection(&PerfDataCriticalSection);
406 return CpuUsage;
409 TIME PerfDataGetCPUTime(ULONG Index)
411 TIME CpuTime = {{0,0}};
413 EnterCriticalSection(&PerfDataCriticalSection);
415 if (Index < ProcessCount)
416 CpuTime = pPerfData[Index].CPUTime;
418 LeaveCriticalSection(&PerfDataCriticalSection);
420 return CpuTime;
423 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
425 ULONG WorkingSetSizeBytes;
427 EnterCriticalSection(&PerfDataCriticalSection);
429 if (Index < ProcessCount)
430 WorkingSetSizeBytes = pPerfData[Index].vmCounters.WorkingSetSize;
431 else
432 WorkingSetSizeBytes = 0;
434 LeaveCriticalSection(&PerfDataCriticalSection);
436 return WorkingSetSizeBytes;
439 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
441 ULONG PeakWorkingSetSizeBytes;
443 EnterCriticalSection(&PerfDataCriticalSection);
445 if (Index < ProcessCount)
446 PeakWorkingSetSizeBytes = pPerfData[Index].vmCounters.PeakWorkingSetSize;
447 else
448 PeakWorkingSetSizeBytes = 0;
450 LeaveCriticalSection(&PerfDataCriticalSection);
452 return PeakWorkingSetSizeBytes;
455 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
457 ULONG WorkingSetSizeDelta;
459 EnterCriticalSection(&PerfDataCriticalSection);
461 if (Index < ProcessCount)
462 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
463 else
464 WorkingSetSizeDelta = 0;
466 LeaveCriticalSection(&PerfDataCriticalSection);
468 return WorkingSetSizeDelta;
471 ULONG PerfDataGetPageFaultCount(ULONG Index)
473 ULONG PageFaultCount;
475 EnterCriticalSection(&PerfDataCriticalSection);
477 if (Index < ProcessCount)
478 PageFaultCount = pPerfData[Index].vmCounters.PageFaultCount;
479 else
480 PageFaultCount = 0;
482 LeaveCriticalSection(&PerfDataCriticalSection);
484 return PageFaultCount;
487 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
489 ULONG PageFaultCountDelta;
491 EnterCriticalSection(&PerfDataCriticalSection);
493 if (Index < ProcessCount)
494 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
495 else
496 PageFaultCountDelta = 0;
498 LeaveCriticalSection(&PerfDataCriticalSection);
500 return PageFaultCountDelta;
503 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
505 ULONG VirtualMemorySizeBytes;
507 EnterCriticalSection(&PerfDataCriticalSection);
509 if (Index < ProcessCount)
510 VirtualMemorySizeBytes = pPerfData[Index].vmCounters.VirtualSize;
511 else
512 VirtualMemorySizeBytes = 0;
514 LeaveCriticalSection(&PerfDataCriticalSection);
516 return VirtualMemorySizeBytes;
519 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
521 ULONG PagedPoolUsagePages;
523 EnterCriticalSection(&PerfDataCriticalSection);
525 if (Index < ProcessCount)
526 PagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaPagedPoolUsage;
527 else
528 PagedPoolUsagePages = 0;
530 LeaveCriticalSection(&PerfDataCriticalSection);
532 return PagedPoolUsagePages;
535 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
537 ULONG NonPagedPoolUsagePages;
539 EnterCriticalSection(&PerfDataCriticalSection);
541 if (Index < ProcessCount)
542 NonPagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaNonPagedPoolUsage;
543 else
544 NonPagedPoolUsagePages = 0;
546 LeaveCriticalSection(&PerfDataCriticalSection);
548 return NonPagedPoolUsagePages;
551 ULONG PerfDataGetBasePriority(ULONG Index)
553 ULONG BasePriority;
555 EnterCriticalSection(&PerfDataCriticalSection);
557 if (Index < ProcessCount)
558 BasePriority = pPerfData[Index].BasePriority;
559 else
560 BasePriority = 0;
562 LeaveCriticalSection(&PerfDataCriticalSection);
564 return BasePriority;
567 ULONG PerfDataGetHandleCount(ULONG Index)
569 ULONG HandleCount;
571 EnterCriticalSection(&PerfDataCriticalSection);
573 if (Index < ProcessCount)
574 HandleCount = pPerfData[Index].HandleCount;
575 else
576 HandleCount = 0;
578 LeaveCriticalSection(&PerfDataCriticalSection);
580 return HandleCount;
583 ULONG PerfDataGetThreadCount(ULONG Index)
585 ULONG ThreadCount;
587 EnterCriticalSection(&PerfDataCriticalSection);
589 if (Index < ProcessCount)
590 ThreadCount = pPerfData[Index].ThreadCount;
591 else
592 ThreadCount = 0;
594 LeaveCriticalSection(&PerfDataCriticalSection);
596 return ThreadCount;
599 ULONG PerfDataGetUSERObjectCount(ULONG Index)
601 ULONG USERObjectCount;
603 EnterCriticalSection(&PerfDataCriticalSection);
605 if (Index < ProcessCount)
606 USERObjectCount = pPerfData[Index].USERObjectCount;
607 else
608 USERObjectCount = 0;
610 LeaveCriticalSection(&PerfDataCriticalSection);
612 return USERObjectCount;
615 ULONG PerfDataGetGDIObjectCount(ULONG Index)
617 ULONG GDIObjectCount;
619 EnterCriticalSection(&PerfDataCriticalSection);
621 if (Index < ProcessCount)
622 GDIObjectCount = pPerfData[Index].GDIObjectCount;
623 else
624 GDIObjectCount = 0;
626 LeaveCriticalSection(&PerfDataCriticalSection);
628 return GDIObjectCount;
631 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
633 BOOL bSuccessful;
635 EnterCriticalSection(&PerfDataCriticalSection);
637 if (Index < ProcessCount)
639 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
640 bSuccessful = TRUE;
642 else
643 bSuccessful = FALSE;
645 LeaveCriticalSection(&PerfDataCriticalSection);
647 return bSuccessful;
650 ULONG PerfDataGetCommitChargeTotalK(void)
652 ULONG Total;
653 ULONG PageSize;
655 EnterCriticalSection(&PerfDataCriticalSection);
657 Total = SystemPerfInfo.TotalCommittedPages;
658 PageSize = SystemBasicInfo.PageSize;
660 LeaveCriticalSection(&PerfDataCriticalSection);
662 Total = Total * (PageSize / 1024);
664 return Total;
667 ULONG PerfDataGetCommitChargeLimitK(void)
669 ULONG Limit;
670 ULONG PageSize;
672 EnterCriticalSection(&PerfDataCriticalSection);
674 Limit = SystemPerfInfo.TotalCommitLimit;
675 PageSize = SystemBasicInfo.PageSize;
677 LeaveCriticalSection(&PerfDataCriticalSection);
679 Limit = Limit * (PageSize / 1024);
681 return Limit;
684 ULONG PerfDataGetCommitChargePeakK(void)
686 ULONG Peak;
687 ULONG PageSize;
689 EnterCriticalSection(&PerfDataCriticalSection);
691 Peak = SystemPerfInfo.PeakCommitment;
692 PageSize = SystemBasicInfo.PageSize;
694 LeaveCriticalSection(&PerfDataCriticalSection);
696 Peak = Peak * (PageSize / 1024);
698 return Peak;
701 ULONG PerfDataGetKernelMemoryTotalK(void)
703 ULONG Total;
704 ULONG Paged;
705 ULONG NonPaged;
706 ULONG PageSize;
708 EnterCriticalSection(&PerfDataCriticalSection);
710 Paged = SystemPerfInfo.PagedPoolUsage;
711 NonPaged = SystemPerfInfo.NonPagedPoolUsage;
712 PageSize = SystemBasicInfo.PageSize;
714 LeaveCriticalSection(&PerfDataCriticalSection);
716 Paged = Paged * (PageSize / 1024);
717 NonPaged = NonPaged * (PageSize / 1024);
719 Total = Paged + NonPaged;
721 return Total;
724 ULONG PerfDataGetKernelMemoryPagedK(void)
726 ULONG Paged;
727 ULONG PageSize;
729 EnterCriticalSection(&PerfDataCriticalSection);
731 Paged = SystemPerfInfo.PagedPoolUsage;
732 PageSize = SystemBasicInfo.PageSize;
734 LeaveCriticalSection(&PerfDataCriticalSection);
736 Paged = Paged * (PageSize / 1024);
738 return Paged;
741 ULONG PerfDataGetKernelMemoryNonPagedK(void)
743 ULONG NonPaged;
744 ULONG PageSize;
746 EnterCriticalSection(&PerfDataCriticalSection);
748 NonPaged = SystemPerfInfo.NonPagedPoolUsage;
749 PageSize = SystemBasicInfo.PageSize;
751 LeaveCriticalSection(&PerfDataCriticalSection);
753 NonPaged = NonPaged * (PageSize / 1024);
755 return NonPaged;
758 ULONG PerfDataGetPhysicalMemoryTotalK(void)
760 ULONG Total;
761 ULONG PageSize;
763 EnterCriticalSection(&PerfDataCriticalSection);
765 Total = SystemBasicInfo.MmNumberOfPhysicalPages;
766 PageSize = SystemBasicInfo.PageSize;
768 LeaveCriticalSection(&PerfDataCriticalSection);
770 Total = Total * (PageSize / 1024);
772 return Total;
775 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
777 ULONG Available;
778 ULONG PageSize;
780 EnterCriticalSection(&PerfDataCriticalSection);
782 Available = SystemPerfInfo.AvailablePages;
783 PageSize = SystemBasicInfo.PageSize;
785 LeaveCriticalSection(&PerfDataCriticalSection);
787 Available = Available * (PageSize / 1024);
789 return Available;
792 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
794 ULONG SystemCache;
796 EnterCriticalSection(&PerfDataCriticalSection);
798 SystemCache = SystemCacheInfo.CurrentSize;
800 LeaveCriticalSection(&PerfDataCriticalSection);
802 SystemCache = SystemCache / 1024;
804 return SystemCache;
807 ULONG PerfDataGetSystemHandleCount(void)
809 ULONG HandleCount;
811 EnterCriticalSection(&PerfDataCriticalSection);
813 HandleCount = SystemHandleInfo.Count;
815 LeaveCriticalSection(&PerfDataCriticalSection);
817 return HandleCount;
820 ULONG PerfDataGetTotalThreadCount(void)
822 ULONG ThreadCount = 0;
823 ULONG i;
825 EnterCriticalSection(&PerfDataCriticalSection);
827 for (i=0; i<ProcessCount; i++)
829 ThreadCount += pPerfData[i].ThreadCount;
832 LeaveCriticalSection(&PerfDataCriticalSection);
834 return ThreadCount;