📄 performance.c
字号:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "performance.h"
#include "common.h"
#include "utils.h"
#ifdef WIN32
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
#else
#define MEMSIZECMD "/usr/sbin/prtconf 2>/dev/null | awk 'BEGIN{count=0;}/^Memory [Ss]ize/{count=$3*1024;}END{printf \"%.0f\",count}'"
#define PHYSICAL_MEMORY_COMMAND "cat /proc/meminfo | awk 'BEGIN{total=0;free=0;}{if($1~/MemTotal/)total=$2;if($1~/MemFree/)free=$2;}END{printf \"%.0f,%.0f\",total,free}'"
#define SYSTEMSTATCMD "vmstat 1 2| awk 'BEGIN{free_flag = 0;id_flag = 0;}\
{if($0~/fre/ && $0~/id/)\
{for(i=1;i<=NF;i++){if($i~/fre/)free_flag = i;if($i~/id/)id_flag = i;}\
getline;getline;printf \"%.0f,%d\",$free_flag,100 - $id_flag;}}'"
#endif
#ifdef WIN32
typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;
typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;
typedef struct {
USHORT Length;
USHORT MaxLen;
USHORT *Buffer;
} UNICODE_STRING;
typedef struct _THREAD_INFO
{
LARGE_INTEGER CreateTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD StartEIP;
DWORD dwOwnerPID;
DWORD dwThreadId;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD Unknown;
DWORD WaitReason;
}THREADINFO, *PTHREADINFO;
struct process_info
{
DWORD dwOffset;
DWORD dwThreadsCount;
DWORD dwUnused1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
DWORD dwBasePriority;
DWORD dwProcessID;
DWORD dwParentProcessId;
DWORD dwHandleCount;
DWORD dwUnused3[2];
DWORD dwVirtualBytesPeak;
DWORD dwVirtualBytes;
ULONG dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwWorkingSet;
DWORD dwQuotaPeakPagedPoolUsage;
DWORD dwQuotaPagedPoolUsage;
DWORD dwQuotaPeakNonPagedPoolUsage;
DWORD dwQuotaNonPagedPoolUsage;
DWORD dwPageFileUsage;
DWORD dwPageFileUsagePeak;
DWORD dCommitCharge;
THREADINFO ThreadSysInfo[1];
};
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
#endif
#ifdef WIN32
int GetSysCpuUsage(float *percent, char *errbuf)
{
LARGE_INTEGER liOldIdleTime = {0};
LARGE_INTEGER liOldSystemTime = {0};
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
PROCNTQSI NtQuerySystemInformation;
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);
if (!NtQuerySystemInformation)
{
strcpy(errbuf, "2:GetProcAddress() error");
return -1;
}
status = NtQuerySystemInformation(SystemTimeInformation,
&SysTimeInfo,sizeof(SysTimeInfo),NULL);
if (status!=NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation(SystemTimeInformation) error");
return -1;
}
status = NtQuerySystemInformation(SystemPerformanceInformation,
&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation(SystemPerformanceInformation) error");
return -1;
}
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;
Sleep(500);
status = NtQuerySystemInformation(SystemBasicInformation,
&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation(SystemBasicInformation) error");
return -1;
}
status = NtQuerySystemInformation(SystemTimeInformation,
&SysTimeInfo,sizeof(SysTimeInfo),NULL);
if (status!=NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation(SystemTimeInformation) error");
return -1;
}
status = NtQuerySystemInformation(SystemPerformanceInformation,
&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation(SystemPerformanceInformation) error");
return -1;
}
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
*percent = (float)dbIdleTime / (float)dbSystemTime;
*percent = 100.0 - *percent * 100.0 / (float)SysBaseInfo.bKeNumberProcessors + 0.5;
if (*percent > 100)
{
*percent = 100.00;
}
if (*percent < 0)
{
strcpy(errbuf, "2:get cpu load error");
return -1;
}
return 0;
}
int GetSysMemUsage(float *percent, char *errbuf)
{
MEMORYSTATUSEX MemStat;
unsigned long ulAvailPhys = 0,ulTotalPhys = 0;
int ret;
memset(&MemStat,0,sizeof(MemStat));
MemStat.dwLength = sizeof(MEMORYSTATUSEX);
ret = GlobalMemoryStatusEx(&MemStat);
if (!ret)
{
strcpy(errbuf, "2:GlobalMemoryStatusEx() error");
return -1;
}
ulAvailPhys = MemStat.ullAvailPhys;
ulTotalPhys = MemStat.ullTotalPhys;
*percent = 100 - 100*(float)ulAvailPhys/(float)ulTotalPhys;
return 0;
}
int GetSysMemSize(unsigned long *memsize, char *errbuf)
{
MEMORYSTATUSEX MemStat;
int ret;
memset(&MemStat,0,sizeof(MemStat));
MemStat.dwLength = sizeof(MEMORYSTATUSEX);
ret = GlobalMemoryStatusEx(&MemStat);
if (!ret)
{
strcpy(errbuf, "2:GlobalMemoryStatusEx() error");
return -1;
}
*memsize = MemStat.ullTotalPhys/1024;
return 0;
}
int GetProcCpuUsage(unsigned int pid, float *percent, char *errbuf)
{
LONG status;
void *pProcInfo = NULL;
struct process_info *pProcessInfo;
DWORD dwInfoSize = 0x80000;
__int64 LastTotalProcessCPUUsage = 0;
__int64 TotalProcessCPUUsage = 0;
DWORD TotalDelta = 0;
__int64 cpuload = 0;
PROCNTQSI NtQuerySystemInformation;
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle( "ntdll.dll" ),
"NtQuerySystemInformation" );
if (!NtQuerySystemInformation)
{
strcpy(errbuf, "2:GetProcAddress() error");
return -1;
}
pProcInfo = malloc(dwInfoSize);
if(!pProcInfo)
{
return -1;
}
memset(pProcInfo, 0, dwInfoSize);
status = NtQuerySystemInformation(5, pProcInfo, dwInfoSize, 0);
if (status!=NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation() error");
free(pProcInfo);
return -1;
}
pProcessInfo = (struct process_info *)pProcInfo;
while(1)
{
TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
if(pid == pProcessInfo->dwProcessID)
{
cpuload = (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
}
if(pProcessInfo->dwOffset == 0)
{
break;
}
pProcessInfo = (struct process_info *)((byte*)pProcessInfo + pProcessInfo->dwOffset);
}
LastTotalProcessCPUUsage = TotalProcessCPUUsage;
Sleep(500);
memset(pProcInfo, 0, dwInfoSize);
status = NtQuerySystemInformation(5, pProcInfo, dwInfoSize, 0);
if (status!=NO_ERROR)
{
strcpy(errbuf, "2:NtQuerySystemInformation() error");
free(pProcInfo);
return -1;
}
pProcessInfo = (struct process_info *)pProcInfo;
while(1)
{
TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
if(pid == pProcessInfo->dwProcessID)
{
cpuload = (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart - cpuload;
}
if(pProcessInfo->dwOffset == 0)
{
break;
}
pProcessInfo = (struct process_info *)((byte*)pProcessInfo + pProcessInfo->dwOffset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -