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 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
35 PROCNTQSI NtQuerySystemInformation = NULL;
36 PROCGGR pGetGuiResources = NULL;
37 PROCGPIC pGetProcessIoCounters = NULL;
38 CRITICAL_SECTION PerfDataCriticalSection;
39 PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */
40 PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */
41 ULONG ProcessCountOld = 0;
42 ULONG ProcessCount = 0;
46 LARGE_INTEGER liOldIdleTime = {{0,0}};
47 double OldKernelTime = 0;
48 LARGE_INTEGER liOldSystemTime = {{0,0}};
49 SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
50 SYSTEM_BASIC_INFORMATION SystemBasicInfo;
51 SYSTEM_CACHE_INFORMATION SystemCacheInfo;
52 SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
53 PSYSTEM_PROCESSORTIME_INFO SystemProcessorTimeInfo = NULL;
55 BOOL PerfDataInitialize(void)
59 NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQuerySystemInformation");
60 pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetGuiResources");
61 pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetProcessIoCounters");
63 InitializeCriticalSection(&PerfDataCriticalSection);
65 if (!NtQuerySystemInformation)
69 * Get number of processors in the system
71 status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
72 if (status != NO_ERROR)
78 void PerfDataUninitialize(void)
80 NtQuerySystemInformation = NULL;
82 DeleteCriticalSection(&PerfDataCriticalSection);
85 void PerfDataRefresh(void)
91 PSYSTEM_PROCESS_INFORMATION pSPI;
96 TCHAR szTemp[MAX_PATH];
98 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
99 SYSTEM_TIME_INFORMATION SysTimeInfo;
100 SYSTEM_CACHE_INFORMATION SysCacheInfo;
101 LPBYTE SysHandleInfoData;
102 PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo;
103 double CurrentKernelTime;
106 if (!NtQuerySystemInformation)
109 /* Get new system time */
110 status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
111 if (status != NO_ERROR)
114 /* Get new CPU's idle time */
115 status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
116 if (status != NO_ERROR)
119 /* Get system cache information */
120 status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
121 if (status != NO_ERROR)
124 /* Get processor time information */
125 SysProcessorTimeInfo = (PSYSTEM_PROCESSORTIME_INFO)malloc(sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors);
126 status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize);
127 if (status != NO_ERROR)
130 /* Get handle information
131 * We don't know how much data there is so just keep
132 * increasing the buffer size until the call succeeds
137 BufferSize += 0x10000;
138 SysHandleInfoData = (LPBYTE)malloc(BufferSize);
140 status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
142 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
143 free(SysHandleInfoData);
146 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
148 /* Get process information
149 * We don't know how much data there is so just keep
150 * increasing the buffer size until the call succeeds
155 BufferSize += 0x10000;
156 pBuffer = (LPBYTE)malloc(BufferSize);
158 status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
160 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
164 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
166 EnterCriticalSection(&PerfDataCriticalSection);
169 * Save system performance info
171 memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
174 * Save system cache info
176 memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
179 * Save system processor time info
181 free(SystemProcessorTimeInfo);
182 SystemProcessorTimeInfo = SysProcessorTimeInfo;
185 * Save system handle info
187 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
188 free(SysHandleInfoData);
190 for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
191 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
192 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
193 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
196 /* If it's a first call - skip idle time calcs */
197 if (liOldIdleTime.QuadPart != 0) {
198 /* CurrentValue = NewValue - OldValue */
199 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
200 dbKernelTime = CurrentKernelTime - OldKernelTime;
201 dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
203 /* CurrentCpuIdle = IdleTime / SystemTime */
204 dbIdleTime = dbIdleTime / dbSystemTime;
205 dbKernelTime = dbKernelTime / dbSystemTime;
207 /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
208 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
209 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
212 /* Store new CPU's idle and system time */
213 liOldIdleTime = SysPerfInfo.liIdleTime;
214 liOldSystemTime = SysTimeInfo.liKeSystemTime;
215 OldKernelTime = CurrentKernelTime;
217 /* Determine the process count
218 * We loop through the data we got from NtQuerySystemInformation
219 * and count how many structures there are (until RelativeOffset is 0)
221 ProcessCountOld = ProcessCount;
223 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
226 if (pSPI->RelativeOffset == 0)
228 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
231 /* Now alloc a new PERFDATA array and fill in the data */
233 pPerfDataOld = pPerfData;
234 pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount);
235 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
236 for (Idx=0; Idx<ProcessCount; Idx++) {
237 /* Get the old perf data for this process (if any) */
238 /* so that we can establish delta values */
240 for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
241 if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
242 pPDOld = &pPerfDataOld[Idx2];
247 /* Clear out process perf data structure */
248 memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
250 if (pSPI->Name.Buffer)
251 lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
254 static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0};
255 lstrcpyW(pPerfData[Idx].ImageName, idleW );
258 pPerfData[Idx].ProcessId = pSPI->ProcessId;
261 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
262 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
263 double CpuTime = (CurTime - OldTime) / dbSystemTime;
264 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
265 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
267 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
268 pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
269 pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
271 pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
273 pPerfData[Idx].WorkingSetSizeDelta = 0;
274 pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
276 pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
278 pPerfData[Idx].PageFaultCountDelta = 0;
279 pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
280 pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
281 pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
282 pPerfData[Idx].BasePriority = pSPI->BasePriority;
283 pPerfData[Idx].HandleCount = pSPI->HandleCount;
284 pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
285 pPerfData[Idx].SessionId = pSPI->SessionId;
287 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
289 if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
290 ImpersonateLoggedOnUser(hProcessToken);
291 memset(szTemp, 0, sizeof(TCHAR[MAX_PATH]));
293 GetUserName(szTemp, &dwSize);
295 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
297 int MultiByteToWideChar(
298 UINT CodePage, // code page
299 DWORD dwFlags, // character-type options
300 LPCSTR lpMultiByteStr, // string to map
301 int cbMultiByte, // number of bytes in string
302 LPWSTR lpWideCharStr, // wide-character buffer
303 int cchWideChar // size of buffer
308 CloseHandle(hProcessToken);
310 if (pGetGuiResources) {
311 pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
312 pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
314 if (pGetProcessIoCounters)
315 pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
316 CloseHandle(hProcess);
318 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
319 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
320 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
323 LeaveCriticalSection(&PerfDataCriticalSection);
326 ULONG PerfDataGetProcessCount(void)
331 ULONG PerfDataGetProcessorUsage(void)
333 return (ULONG)dbIdleTime;
336 ULONG PerfDataGetProcessorSystemUsage(void)
338 return (ULONG)dbKernelTime;
341 BOOL PerfDataGetImageName(ULONG Index, LPTSTR lpImageName, int nMaxCount)
345 EnterCriticalSection(&PerfDataCriticalSection);
347 if (Index < ProcessCount) {
349 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
351 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].ImageName, -1, lpImageName, nMaxCount, NULL, NULL);
358 LeaveCriticalSection(&PerfDataCriticalSection);
362 ULONG PerfDataGetProcessId(ULONG Index)
366 EnterCriticalSection(&PerfDataCriticalSection);
368 if (Index < ProcessCount)
369 ProcessId = pPerfData[Index].ProcessId;
373 LeaveCriticalSection(&PerfDataCriticalSection);
378 BOOL PerfDataGetUserName(ULONG Index, LPTSTR lpUserName, int nMaxCount)
382 EnterCriticalSection(&PerfDataCriticalSection);
384 if (Index < ProcessCount) {
386 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
388 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].UserName, -1, lpUserName, nMaxCount, NULL, NULL);
396 LeaveCriticalSection(&PerfDataCriticalSection);
401 ULONG PerfDataGetSessionId(ULONG Index)
405 EnterCriticalSection(&PerfDataCriticalSection);
407 if (Index < ProcessCount)
408 SessionId = pPerfData[Index].SessionId;
412 LeaveCriticalSection(&PerfDataCriticalSection);
417 ULONG PerfDataGetCPUUsage(ULONG Index)
421 EnterCriticalSection(&PerfDataCriticalSection);
423 if (Index < ProcessCount)
424 CpuUsage = pPerfData[Index].CPUUsage;
428 LeaveCriticalSection(&PerfDataCriticalSection);
433 TIME PerfDataGetCPUTime(ULONG Index)
435 TIME CpuTime = {{0,0}};
437 EnterCriticalSection(&PerfDataCriticalSection);
439 if (Index < ProcessCount)
440 CpuTime = pPerfData[Index].CPUTime;
442 LeaveCriticalSection(&PerfDataCriticalSection);
447 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
449 ULONG WorkingSetSizeBytes;
451 EnterCriticalSection(&PerfDataCriticalSection);
453 if (Index < ProcessCount)
454 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
456 WorkingSetSizeBytes = 0;
458 LeaveCriticalSection(&PerfDataCriticalSection);
460 return WorkingSetSizeBytes;
463 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
465 ULONG PeakWorkingSetSizeBytes;
467 EnterCriticalSection(&PerfDataCriticalSection);
469 if (Index < ProcessCount)
470 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
472 PeakWorkingSetSizeBytes = 0;
474 LeaveCriticalSection(&PerfDataCriticalSection);
476 return PeakWorkingSetSizeBytes;
479 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
481 ULONG WorkingSetSizeDelta;
483 EnterCriticalSection(&PerfDataCriticalSection);
485 if (Index < ProcessCount)
486 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
488 WorkingSetSizeDelta = 0;
490 LeaveCriticalSection(&PerfDataCriticalSection);
492 return WorkingSetSizeDelta;
495 ULONG PerfDataGetPageFaultCount(ULONG Index)
497 ULONG PageFaultCount;
499 EnterCriticalSection(&PerfDataCriticalSection);
501 if (Index < ProcessCount)
502 PageFaultCount = pPerfData[Index].PageFaultCount;
506 LeaveCriticalSection(&PerfDataCriticalSection);
508 return PageFaultCount;
511 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
513 ULONG PageFaultCountDelta;
515 EnterCriticalSection(&PerfDataCriticalSection);
517 if (Index < ProcessCount)
518 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
520 PageFaultCountDelta = 0;
522 LeaveCriticalSection(&PerfDataCriticalSection);
524 return PageFaultCountDelta;
527 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
529 ULONG VirtualMemorySizeBytes;
531 EnterCriticalSection(&PerfDataCriticalSection);
533 if (Index < ProcessCount)
534 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
536 VirtualMemorySizeBytes = 0;
538 LeaveCriticalSection(&PerfDataCriticalSection);
540 return VirtualMemorySizeBytes;
543 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
545 ULONG PagedPoolUsagePages;
547 EnterCriticalSection(&PerfDataCriticalSection);
549 if (Index < ProcessCount)
550 PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages;
552 PagedPoolUsagePages = 0;
554 LeaveCriticalSection(&PerfDataCriticalSection);
556 return PagedPoolUsagePages;
559 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
561 ULONG NonPagedPoolUsagePages;
563 EnterCriticalSection(&PerfDataCriticalSection);
565 if (Index < ProcessCount)
566 NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages;
568 NonPagedPoolUsagePages = 0;
570 LeaveCriticalSection(&PerfDataCriticalSection);
572 return NonPagedPoolUsagePages;
575 ULONG PerfDataGetBasePriority(ULONG Index)
579 EnterCriticalSection(&PerfDataCriticalSection);
581 if (Index < ProcessCount)
582 BasePriority = pPerfData[Index].BasePriority;
586 LeaveCriticalSection(&PerfDataCriticalSection);
591 ULONG PerfDataGetHandleCount(ULONG Index)
595 EnterCriticalSection(&PerfDataCriticalSection);
597 if (Index < ProcessCount)
598 HandleCount = pPerfData[Index].HandleCount;
602 LeaveCriticalSection(&PerfDataCriticalSection);
607 ULONG PerfDataGetThreadCount(ULONG Index)
611 EnterCriticalSection(&PerfDataCriticalSection);
613 if (Index < ProcessCount)
614 ThreadCount = pPerfData[Index].ThreadCount;
618 LeaveCriticalSection(&PerfDataCriticalSection);
623 ULONG PerfDataGetUSERObjectCount(ULONG Index)
625 ULONG USERObjectCount;
627 EnterCriticalSection(&PerfDataCriticalSection);
629 if (Index < ProcessCount)
630 USERObjectCount = pPerfData[Index].USERObjectCount;
634 LeaveCriticalSection(&PerfDataCriticalSection);
636 return USERObjectCount;
639 ULONG PerfDataGetGDIObjectCount(ULONG Index)
641 ULONG GDIObjectCount;
643 EnterCriticalSection(&PerfDataCriticalSection);
645 if (Index < ProcessCount)
646 GDIObjectCount = pPerfData[Index].GDIObjectCount;
650 LeaveCriticalSection(&PerfDataCriticalSection);
652 return GDIObjectCount;
655 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
659 EnterCriticalSection(&PerfDataCriticalSection);
661 if (Index < ProcessCount)
663 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
669 LeaveCriticalSection(&PerfDataCriticalSection);
674 ULONG PerfDataGetCommitChargeTotalK(void)
679 EnterCriticalSection(&PerfDataCriticalSection);
681 Total = SystemPerfInfo.MmTotalCommitedPages;
682 PageSize = SystemBasicInfo.uPageSize;
684 LeaveCriticalSection(&PerfDataCriticalSection);
686 Total = Total * (PageSize / 1024);
691 ULONG PerfDataGetCommitChargeLimitK(void)
696 EnterCriticalSection(&PerfDataCriticalSection);
698 Limit = SystemPerfInfo.MmTotalCommitLimit;
699 PageSize = SystemBasicInfo.uPageSize;
701 LeaveCriticalSection(&PerfDataCriticalSection);
703 Limit = Limit * (PageSize / 1024);
708 ULONG PerfDataGetCommitChargePeakK(void)
713 EnterCriticalSection(&PerfDataCriticalSection);
715 Peak = SystemPerfInfo.MmPeakLimit;
716 PageSize = SystemBasicInfo.uPageSize;
718 LeaveCriticalSection(&PerfDataCriticalSection);
720 Peak = Peak * (PageSize / 1024);
725 ULONG PerfDataGetKernelMemoryTotalK(void)
732 EnterCriticalSection(&PerfDataCriticalSection);
734 Paged = SystemPerfInfo.PoolPagedBytes;
735 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
736 PageSize = SystemBasicInfo.uPageSize;
738 LeaveCriticalSection(&PerfDataCriticalSection);
740 Paged = Paged * (PageSize / 1024);
741 NonPaged = NonPaged * (PageSize / 1024);
743 Total = Paged + NonPaged;
748 ULONG PerfDataGetKernelMemoryPagedK(void)
753 EnterCriticalSection(&PerfDataCriticalSection);
755 Paged = SystemPerfInfo.PoolPagedBytes;
756 PageSize = SystemBasicInfo.uPageSize;
758 LeaveCriticalSection(&PerfDataCriticalSection);
760 Paged = Paged * (PageSize / 1024);
765 ULONG PerfDataGetKernelMemoryNonPagedK(void)
770 EnterCriticalSection(&PerfDataCriticalSection);
772 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
773 PageSize = SystemBasicInfo.uPageSize;
775 LeaveCriticalSection(&PerfDataCriticalSection);
777 NonPaged = NonPaged * (PageSize / 1024);
782 ULONG PerfDataGetPhysicalMemoryTotalK(void)
787 EnterCriticalSection(&PerfDataCriticalSection);
789 Total = SystemBasicInfo.uMmNumberOfPhysicalPages;
790 PageSize = SystemBasicInfo.uPageSize;
792 LeaveCriticalSection(&PerfDataCriticalSection);
794 Total = Total * (PageSize / 1024);
799 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
804 EnterCriticalSection(&PerfDataCriticalSection);
806 Available = SystemPerfInfo.MmAvailablePages;
807 PageSize = SystemBasicInfo.uPageSize;
809 LeaveCriticalSection(&PerfDataCriticalSection);
811 Available = Available * (PageSize / 1024);
816 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
821 EnterCriticalSection(&PerfDataCriticalSection);
823 SystemCache = SystemCacheInfo.CurrentSize;
824 PageSize = SystemBasicInfo.uPageSize;
826 LeaveCriticalSection(&PerfDataCriticalSection);
828 /* SystemCache = SystemCache * (PageSize / 1024); */
829 SystemCache = SystemCache / 1024;
834 ULONG PerfDataGetSystemHandleCount(void)
838 EnterCriticalSection(&PerfDataCriticalSection);
840 HandleCount = SystemHandleInfo.Count;
842 LeaveCriticalSection(&PerfDataCriticalSection);
847 ULONG PerfDataGetTotalThreadCount(void)
849 ULONG ThreadCount = 0;
852 EnterCriticalSection(&PerfDataCriticalSection);
854 for (i=0; i<ProcessCount; i++)
856 ThreadCount += pPerfData[i].ThreadCount;
859 LeaveCriticalSection(&PerfDataCriticalSection);