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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 if (SystemProcessorTimeInfo) {
182 free(SystemProcessorTimeInfo);
184 SystemProcessorTimeInfo = SysProcessorTimeInfo;
187 * Save system handle info
189 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
190 free(SysHandleInfoData);
192 for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
193 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
194 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
195 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
198 /* If it's a first call - skip idle time calcs */
199 if (liOldIdleTime.QuadPart != 0) {
200 /* CurrentValue = NewValue - OldValue */
201 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
202 dbKernelTime = CurrentKernelTime - OldKernelTime;
203 dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
205 /* CurrentCpuIdle = IdleTime / SystemTime */
206 dbIdleTime = dbIdleTime / dbSystemTime;
207 dbKernelTime = dbKernelTime / dbSystemTime;
209 /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
210 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
211 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
214 /* Store new CPU's idle and system time */
215 liOldIdleTime = SysPerfInfo.liIdleTime;
216 liOldSystemTime = SysTimeInfo.liKeSystemTime;
217 OldKernelTime = CurrentKernelTime;
219 /* Determine the process count
220 * We loop through the data we got from NtQuerySystemInformation
221 * and count how many structures there are (until RelativeOffset is 0)
223 ProcessCountOld = ProcessCount;
225 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
228 if (pSPI->RelativeOffset == 0)
230 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
233 /* Now alloc a new PERFDATA array and fill in the data */
237 pPerfDataOld = pPerfData;
238 pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount);
239 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
240 for (Idx=0; Idx<ProcessCount; Idx++) {
241 /* Get the old perf data for this process (if any) */
242 /* so that we can establish delta values */
244 for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
245 if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
246 pPDOld = &pPerfDataOld[Idx2];
251 /* Clear out process perf data structure */
252 memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
254 if (pSPI->Name.Buffer)
255 lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
258 static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0};
259 lstrcpyW(pPerfData[Idx].ImageName, idleW );
262 pPerfData[Idx].ProcessId = pSPI->ProcessId;
265 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
266 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
267 double CpuTime = (CurTime - OldTime) / dbSystemTime;
268 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
269 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
271 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
272 pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
273 pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
275 pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
277 pPerfData[Idx].WorkingSetSizeDelta = 0;
278 pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
280 pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
282 pPerfData[Idx].PageFaultCountDelta = 0;
283 pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
284 pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
285 pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
286 pPerfData[Idx].BasePriority = pSPI->BasePriority;
287 pPerfData[Idx].HandleCount = pSPI->HandleCount;
288 pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
289 pPerfData[Idx].SessionId = pSPI->SessionId;
291 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
293 if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
294 ImpersonateLoggedOnUser(hProcessToken);
295 memset(szTemp, 0, sizeof(TCHAR[MAX_PATH]));
297 GetUserName(szTemp, &dwSize);
299 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
301 int MultiByteToWideChar(
302 UINT CodePage, // code page
303 DWORD dwFlags, // character-type options
304 LPCSTR lpMultiByteStr, // string to map
305 int cbMultiByte, // number of bytes in string
306 LPWSTR lpWideCharStr, // wide-character buffer
307 int cchWideChar // size of buffer
312 CloseHandle(hProcessToken);
314 if (pGetGuiResources) {
315 pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
316 pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
318 if (pGetProcessIoCounters)
319 pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
320 CloseHandle(hProcess);
322 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
323 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
324 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
327 LeaveCriticalSection(&PerfDataCriticalSection);
330 ULONG PerfDataGetProcessCount(void)
335 ULONG PerfDataGetProcessorUsage(void)
337 return (ULONG)dbIdleTime;
340 ULONG PerfDataGetProcessorSystemUsage(void)
342 return (ULONG)dbKernelTime;
345 BOOL PerfDataGetImageName(ULONG Index, LPTSTR lpImageName, int nMaxCount)
349 EnterCriticalSection(&PerfDataCriticalSection);
351 if (Index < ProcessCount) {
353 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
355 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].ImageName, -1, lpImageName, nMaxCount, NULL, NULL);
362 LeaveCriticalSection(&PerfDataCriticalSection);
366 ULONG PerfDataGetProcessId(ULONG Index)
370 EnterCriticalSection(&PerfDataCriticalSection);
372 if (Index < ProcessCount)
373 ProcessId = pPerfData[Index].ProcessId;
377 LeaveCriticalSection(&PerfDataCriticalSection);
382 BOOL PerfDataGetUserName(ULONG Index, LPTSTR lpUserName, int nMaxCount)
386 EnterCriticalSection(&PerfDataCriticalSection);
388 if (Index < ProcessCount) {
390 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
392 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].UserName, -1, lpUserName, nMaxCount, NULL, NULL);
400 LeaveCriticalSection(&PerfDataCriticalSection);
405 ULONG PerfDataGetSessionId(ULONG Index)
409 EnterCriticalSection(&PerfDataCriticalSection);
411 if (Index < ProcessCount)
412 SessionId = pPerfData[Index].SessionId;
416 LeaveCriticalSection(&PerfDataCriticalSection);
421 ULONG PerfDataGetCPUUsage(ULONG Index)
425 EnterCriticalSection(&PerfDataCriticalSection);
427 if (Index < ProcessCount)
428 CpuUsage = pPerfData[Index].CPUUsage;
432 LeaveCriticalSection(&PerfDataCriticalSection);
437 TIME PerfDataGetCPUTime(ULONG Index)
439 TIME CpuTime = {{0,0}};
441 EnterCriticalSection(&PerfDataCriticalSection);
443 if (Index < ProcessCount)
444 CpuTime = pPerfData[Index].CPUTime;
446 LeaveCriticalSection(&PerfDataCriticalSection);
451 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
453 ULONG WorkingSetSizeBytes;
455 EnterCriticalSection(&PerfDataCriticalSection);
457 if (Index < ProcessCount)
458 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
460 WorkingSetSizeBytes = 0;
462 LeaveCriticalSection(&PerfDataCriticalSection);
464 return WorkingSetSizeBytes;
467 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
469 ULONG PeakWorkingSetSizeBytes;
471 EnterCriticalSection(&PerfDataCriticalSection);
473 if (Index < ProcessCount)
474 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
476 PeakWorkingSetSizeBytes = 0;
478 LeaveCriticalSection(&PerfDataCriticalSection);
480 return PeakWorkingSetSizeBytes;
483 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
485 ULONG WorkingSetSizeDelta;
487 EnterCriticalSection(&PerfDataCriticalSection);
489 if (Index < ProcessCount)
490 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
492 WorkingSetSizeDelta = 0;
494 LeaveCriticalSection(&PerfDataCriticalSection);
496 return WorkingSetSizeDelta;
499 ULONG PerfDataGetPageFaultCount(ULONG Index)
501 ULONG PageFaultCount;
503 EnterCriticalSection(&PerfDataCriticalSection);
505 if (Index < ProcessCount)
506 PageFaultCount = pPerfData[Index].PageFaultCount;
510 LeaveCriticalSection(&PerfDataCriticalSection);
512 return PageFaultCount;
515 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
517 ULONG PageFaultCountDelta;
519 EnterCriticalSection(&PerfDataCriticalSection);
521 if (Index < ProcessCount)
522 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
524 PageFaultCountDelta = 0;
526 LeaveCriticalSection(&PerfDataCriticalSection);
528 return PageFaultCountDelta;
531 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
533 ULONG VirtualMemorySizeBytes;
535 EnterCriticalSection(&PerfDataCriticalSection);
537 if (Index < ProcessCount)
538 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
540 VirtualMemorySizeBytes = 0;
542 LeaveCriticalSection(&PerfDataCriticalSection);
544 return VirtualMemorySizeBytes;
547 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
549 ULONG PagedPoolUsagePages;
551 EnterCriticalSection(&PerfDataCriticalSection);
553 if (Index < ProcessCount)
554 PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages;
556 PagedPoolUsagePages = 0;
558 LeaveCriticalSection(&PerfDataCriticalSection);
560 return PagedPoolUsagePages;
563 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
565 ULONG NonPagedPoolUsagePages;
567 EnterCriticalSection(&PerfDataCriticalSection);
569 if (Index < ProcessCount)
570 NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages;
572 NonPagedPoolUsagePages = 0;
574 LeaveCriticalSection(&PerfDataCriticalSection);
576 return NonPagedPoolUsagePages;
579 ULONG PerfDataGetBasePriority(ULONG Index)
583 EnterCriticalSection(&PerfDataCriticalSection);
585 if (Index < ProcessCount)
586 BasePriority = pPerfData[Index].BasePriority;
590 LeaveCriticalSection(&PerfDataCriticalSection);
595 ULONG PerfDataGetHandleCount(ULONG Index)
599 EnterCriticalSection(&PerfDataCriticalSection);
601 if (Index < ProcessCount)
602 HandleCount = pPerfData[Index].HandleCount;
606 LeaveCriticalSection(&PerfDataCriticalSection);
611 ULONG PerfDataGetThreadCount(ULONG Index)
615 EnterCriticalSection(&PerfDataCriticalSection);
617 if (Index < ProcessCount)
618 ThreadCount = pPerfData[Index].ThreadCount;
622 LeaveCriticalSection(&PerfDataCriticalSection);
627 ULONG PerfDataGetUSERObjectCount(ULONG Index)
629 ULONG USERObjectCount;
631 EnterCriticalSection(&PerfDataCriticalSection);
633 if (Index < ProcessCount)
634 USERObjectCount = pPerfData[Index].USERObjectCount;
638 LeaveCriticalSection(&PerfDataCriticalSection);
640 return USERObjectCount;
643 ULONG PerfDataGetGDIObjectCount(ULONG Index)
645 ULONG GDIObjectCount;
647 EnterCriticalSection(&PerfDataCriticalSection);
649 if (Index < ProcessCount)
650 GDIObjectCount = pPerfData[Index].GDIObjectCount;
654 LeaveCriticalSection(&PerfDataCriticalSection);
656 return GDIObjectCount;
659 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
663 EnterCriticalSection(&PerfDataCriticalSection);
665 if (Index < ProcessCount)
667 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
673 LeaveCriticalSection(&PerfDataCriticalSection);
678 ULONG PerfDataGetCommitChargeTotalK(void)
683 EnterCriticalSection(&PerfDataCriticalSection);
685 Total = SystemPerfInfo.MmTotalCommitedPages;
686 PageSize = SystemBasicInfo.uPageSize;
688 LeaveCriticalSection(&PerfDataCriticalSection);
690 Total = Total * (PageSize / 1024);
695 ULONG PerfDataGetCommitChargeLimitK(void)
700 EnterCriticalSection(&PerfDataCriticalSection);
702 Limit = SystemPerfInfo.MmTotalCommitLimit;
703 PageSize = SystemBasicInfo.uPageSize;
705 LeaveCriticalSection(&PerfDataCriticalSection);
707 Limit = Limit * (PageSize / 1024);
712 ULONG PerfDataGetCommitChargePeakK(void)
717 EnterCriticalSection(&PerfDataCriticalSection);
719 Peak = SystemPerfInfo.MmPeakLimit;
720 PageSize = SystemBasicInfo.uPageSize;
722 LeaveCriticalSection(&PerfDataCriticalSection);
724 Peak = Peak * (PageSize / 1024);
729 ULONG PerfDataGetKernelMemoryTotalK(void)
736 EnterCriticalSection(&PerfDataCriticalSection);
738 Paged = SystemPerfInfo.PoolPagedBytes;
739 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
740 PageSize = SystemBasicInfo.uPageSize;
742 LeaveCriticalSection(&PerfDataCriticalSection);
744 Paged = Paged * (PageSize / 1024);
745 NonPaged = NonPaged * (PageSize / 1024);
747 Total = Paged + NonPaged;
752 ULONG PerfDataGetKernelMemoryPagedK(void)
757 EnterCriticalSection(&PerfDataCriticalSection);
759 Paged = SystemPerfInfo.PoolPagedBytes;
760 PageSize = SystemBasicInfo.uPageSize;
762 LeaveCriticalSection(&PerfDataCriticalSection);
764 Paged = Paged * (PageSize / 1024);
769 ULONG PerfDataGetKernelMemoryNonPagedK(void)
774 EnterCriticalSection(&PerfDataCriticalSection);
776 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
777 PageSize = SystemBasicInfo.uPageSize;
779 LeaveCriticalSection(&PerfDataCriticalSection);
781 NonPaged = NonPaged * (PageSize / 1024);
786 ULONG PerfDataGetPhysicalMemoryTotalK(void)
791 EnterCriticalSection(&PerfDataCriticalSection);
793 Total = SystemBasicInfo.uMmNumberOfPhysicalPages;
794 PageSize = SystemBasicInfo.uPageSize;
796 LeaveCriticalSection(&PerfDataCriticalSection);
798 Total = Total * (PageSize / 1024);
803 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
808 EnterCriticalSection(&PerfDataCriticalSection);
810 Available = SystemPerfInfo.MmAvailablePages;
811 PageSize = SystemBasicInfo.uPageSize;
813 LeaveCriticalSection(&PerfDataCriticalSection);
815 Available = Available * (PageSize / 1024);
820 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
825 EnterCriticalSection(&PerfDataCriticalSection);
827 SystemCache = SystemCacheInfo.CurrentSize;
828 PageSize = SystemBasicInfo.uPageSize;
830 LeaveCriticalSection(&PerfDataCriticalSection);
832 /* SystemCache = SystemCache * (PageSize / 1024); */
833 SystemCache = SystemCache / 1024;
838 ULONG PerfDataGetSystemHandleCount(void)
842 EnterCriticalSection(&PerfDataCriticalSection);
844 HandleCount = SystemHandleInfo.Count;
846 LeaveCriticalSection(&PerfDataCriticalSection);
851 ULONG PerfDataGetTotalThreadCount(void)
853 ULONG ThreadCount = 0;
856 EnterCriticalSection(&PerfDataCriticalSection);
858 for (i=0; i<ProcessCount; i++)
860 ThreadCount += pPerfData[i].ThreadCount;
863 LeaveCriticalSection(&PerfDataCriticalSection);